version 2.0.0-b3

This commit is contained in:
Gerhard Rieger 2009-04-03 17:17:10 +02:00
parent 515c305a7f
commit 5df0e4a3d9
30 changed files with 435 additions and 185 deletions

51
CHANGES
View file

@ -1,4 +1,19 @@
####################### V 2.0.0-b3:
new features:
added inter addresses for execution of external programs or scripts:
EXEC2 and SYSTEM2 are bidirectional, EXEC1 and SYSTEM1 are
unidirectional
option commtype replaces the now obsolete "socketpair" and "pipes"
options and selects the communication mechanism on the left side of
EXEC and SYSTEM addresses
options leftfd, leftinfd, leftoutfd; and rightfd, rightinfd,
rightoutfd override the default file descriptor numbers provided to
exec'd programs
####################### V 2.0.0-b2:
new features:
@ -27,8 +42,42 @@ new features:
new form of FD address with output/input fd numbers
####################### V 1.7.1.0:
new features:
address options shut-none, shut-down, and shut-close allow to control
socat's half close behaviour
with address option shut-null socat sends an empty packet to the peer
to indicate EOF
option null-eof changes the behaviour of sockets that receive an empty
packet to see EOF instead of ignoring it
introduced option names substuser-early and su-e, currently equivalent
to option substuser (thanks to Mike Perry for providing the patch)
corrections:
help displayed some option types wrong
fixed some typos and improved some comments
####################### V 1.7.0.1:
corrections:
fixed possible SIGSEGV in listening addresses when a new connection was
reset by peer before the socket addresses could be retrieved. Thanks to
Mike Perry for sending a patch.
fixed a bug, introduced with version 1.7.0.0, that let client
connections with option connect-timeout fail when the connections
succeeded. Thanks to Bruno De Fraine for reporting this bug.
option end-close "did not apply" to addresses PTY, SOCKET-CONNECT,
and most UNIX-* and ABSTRACT-*
half close of EXEC and SYSTEM addresses did not work for pipes and
sometimes socketpair
help displayed for some option a wrong type
under some circumstances shutdown was called multiple times for the
same fd

View file

@ -230,7 +230,7 @@ $ socat -d -d tcp:localhost:25,crlf,nodelay exec:'/usr/sbin/chat -v -s "\"220 \"
//////////////////////////////////////////////////////////////////////////////
// IP6
# socat readline TCP6:::1:21 # if your inetd/ftp is listening on ip6
# socat readline TCP6:[::1]:21 # if your inetd/ftp is listening on ip6
///////////////////////////////////////////////////////////////////////////////

4
README
View file

@ -50,7 +50,7 @@ following operating systems:
Debian lenny/sid on x86, kernel 2.6.24
FreeBSD 6.1 on x86
NetBSD4.0 on x86
NetBSD 4.0 on x86
OpenBSD 4.3 on x86
OpenSolaris 10 on x86 with gcc
Mac OS X 10.5.5 on iMac G5, with libreadline
@ -75,7 +75,7 @@ install
Get the tarball and extract it:
gtar xzf socat.tar.gz
cd socat-1.7.0.0
cd socat-1.7.1.0
./configure
make
su

View file

@ -1 +1 @@
"2+exec"
"2.0.0-b3"

View file

@ -164,7 +164,7 @@ socat -h |egrep 'openssl-server'</span></span>
<h2>Dual inter addresses</h2>
<p>In socat version 1 it was already possible to combine two unidirectional
addresses to one bidrectional address. This idea has been extended in version
addresses to one bidirectional address. This idea has been extended in version
2: Two unidirectional inter addresses can be combined to one bidirectional
transfer unit.
</p>

View file

@ -1,4 +1,4 @@
<!-- $Revision: 1.1 $ $Date: 2007/03/06 20:54:43 $ -->
<!-- source: doc/socat-multicast.html -->
<html><head>
<title>IP Multicasting with Socat</title>
<link rel="stylesheet" type="text/css" href="dest-unreach.css">
@ -41,8 +41,8 @@ requirements.
All the following examples work bidirectionally except when otherwise noticed.
For "clients" we just use <tt>STDIO</tt>, and for "servers" we use <tt>EXEC:hostname</tt> which
ingores its input but shows us which host the reply comes from. Replace these
addresses with what is appropriate for you (e.g. shell script
invokations). Port 6666 can be replaced with any other port (but for ports &lt;
socat addresses with what is appropriate for your needs (e.g. shell script
invocations). Port 6666 can be replaced with any other port (but for ports &lt;
1024 root privilege might be required).
</p>
<p>
@ -85,7 +85,7 @@ direction the first data is passed.
A packet from the network is accepted by the IP stack for our socket if:
<ul>
<li>it is an incoming UDP/IPv4 packet</li>
<li>its target port matches the local port assigned to the socket (6666)</li>
<li>its target port matches the local port assigned to the socket (random)</li>
<li>its target address matches one of the hosts local addresses or the any-host
multicast address</li>
</ul>
@ -226,9 +226,10 @@ Set a multicast/broadcast route with the following command:</p>
route add -net 224.0.0.0/3 gw 192.168.10.2
</span></span>
<a name="ALLSYSTEMS">
<h3>ALL-SYSTEMS multicast address</h3>
<p>
<a name="ALLSYSTEMS"><tt>224.0.0.1</tt></a> is the all-systems multicast address: all
<tt>224.0.0.1</tt></a> is the all-systems multicast address: all
datagram sockets appear to be automatically member of this group on all
interfaces. This membership cannot be dropped on Linux.
</p>
@ -237,10 +238,14 @@ interfaces. This membership cannot be dropped on Linux.
<h2>(In)Security</h2>
<p>When you use the above examples you should understand that all datagram
sockets without exception accept packets that are directly addressed to them;
sockets without exception accept all packets that are directly addressed to
them;
the multi- and broadcast receiving features are just extensions to the normal
functionality. socat has no way to find out if an incoming packet is addressed
to a unicast, multicast, or broadcast address.</p>
functionality. socat currently has no means to handle incoming packets
differently when it is addressed to a unicast, multicast, or broadcast
address. However, for EXEC'd scripts socat can provide this info in environment
variables.
</p>
<p>Authentication or encryption are not available.</p>
@ -296,13 +301,13 @@ Please note that the new features could not be successfully tested on IPv6;
these sections thus apply to IPv4 only.
</p>
<p>This document was last modified in March 2007.</p>
<p>This document was last modified in April 2009.</p>
<h2>More info about socat datagrams</h2>
<h3>Links regarding this tutorial</h3>
<a href="socat.html#ADDRESS_UDP4_DATAGRAM">address udp4-datagram</a><br>
<a href="socat.html#ADDRESS_UDP4_RECVFROM">address udp4-recvfrom</a><br>
<a href="socat.html#ADDRESS_UDP4_DATAGRAM">address UDP4-DATAGRAM</a><br>
<a href="socat.html#ADDRESS_UDP4_RECVFROM">address UDP4-RECVFROM</a><br>
<a href="socat.html#OPTION_RANGE">option range</a><br>
<a href="socat.html#OPTION_SO_BROADCAST">option broadcast</a><br>
<a href="socat.html#OPTION_IP_ADD_MEMBERSHIP">option ip-add-membership</a><br>
@ -310,11 +315,11 @@ these sections thus apply to IPv4 only.
<a href="socat.html#OPTION_BIND">option bind</a><br>
<h3>Other datagram addresses</h3>
<a href="socat.html#ADDRESS_UDP4_RECV">address udp4-recv</a>: pure datagram receiver<br>
<a href="socat.html#ADDRESS_UDP4_SENDTO">address udp4-sendto</a>: communicate
<a href="socat.html#ADDRESS_UDP4_RECV">address UDP4-RECV</a>: pure datagram receiver<br>
<a href="socat.html#ADDRESS_UDP4_SENDTO">address UDP4-SENDTO</a>: communicate
with one peer address<br>
<a href="socat.html#ADDRESS_UDP4_LISTEN">address udp4-listen</a>: pseudo stream server<br>
<a href="socat.html#ADDRESS_UDP4_CONNECT">address udp4-connect</a>: pseudo stream client<br>
<a href="socat.html#ADDRESS_UDP4_LISTEN">address UDP4-LISTEN</a>: pseudo stream server<br>
<a href="socat.html#ADDRESS_UDP4_CONNECT">address UDP4-CONNECT</a>: pseudo stream client<br>
<h3>Related socat option groups</h3>
<a href="socat.html#GROUP_IP">IP options</a><br>
@ -331,7 +336,7 @@ with one peer address<br>
<a href="http://en.wikipedia.org/wiki/Broadcast_address">broadcasting on Wikipedia</a><br>
<p>
<small>Copyright: Gerhard Rieger 2007</small><br>
<small>Copyright: Gerhard Rieger 2007-2009</small><br>
<small>License: <a href="http://www.fsf.org/licensing/licenses/fdl.html">GNU Free Documentation License (FDL)</a></small>
</p>

View file

@ -1,4 +1,4 @@
<!-- $Revision: 1.1 $ $Date: 2007/03/06 20:54:43 $ -->
<!-- source: doc/socat-tun.html -->
<html><head>
<title>Building TUN based virtual networks with socat</title>
<link rel="stylesheet" type="text/css" href="dest-unreach.css">
@ -16,7 +16,7 @@ these devices are called TUN or TAP.
</p>
<p>
socat provides an address type that creates a TUN device on Linux; the other
socat address can be any type; it transfer the "wire" data as desired.
socat address can be any type; it transfers the "wire" data as desired.
</p>
<p>
This document shows how a simple virtual network can be created between
@ -31,7 +31,7 @@ following commands with the requirements of your situation:</p>
<table border="1">
<tr><th>host</th><th>address</th><th>mask</th></tr>
<tr><td>physical "server" address</td><td>1.2.3.4</td><td>n/a</td></tr>
<tr><td>physical "client" address</td><td>223.2.3.4</td><td>n/a</td></tr>
<tr><td>physical "client" address</td><td>n/a</td><td>n/a</td></tr>
<tr><td>TUN on "server"</td><td>192.168.255.1</td><td>255.255.255.0</td></tr>
<tr><td>TUN on "client"</td><td>192.168.255.2</td><td>255.255.255.0</td></tr>
</table>
@ -140,7 +140,7 @@ transfer.<p>
<p>
Linux TUN/TAP support was added to socat in version 1.6.0.</p>
<p>This document was last modified in March 2007.</p>
<p>This document was last modified in April 2009.</p>
<h2>More info about socat TUN/TAP support</h2>
@ -157,7 +157,7 @@ Linux TUN/TAP support was added to socat in version 1.6.0.</p>
<a href="http://en.wikipedia.org/wiki/TUN/TAP">TUN/TAP on Wikipedia</a><br>
<p>
<small>Copyright: Gerhard Rieger 2007</small><br>
<small>Copyright: Gerhard Rieger 2007-2009</small><br>
<small>License: <a href="http://www.fsf.org/licensing/licenses/fdl.html">GNU Free Documentation License (FDL)</a></small>
</p>

View file

@ -389,13 +389,13 @@ label(ADDRESS_IP_SENDTO)dit(bf(tt(IP-SENDTO:<host>:<protocol>)))
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6) nl()
Useful options:
link(pf)(OPTION_PROTOCOL_FAMILY),
link(ttl)(OPTION_TTL)
link(ttl)(OPTION_TTL) nl()
See also:
link(IP4-SENDTO)(ADDRESS_IP4_SENDTO),
link(IP6-SENDTO)(ADDRESS_IP6_SENDTO),
link(IP-RECVFROM)(ADDRESS_IP_RECVFROM),
link(IP-RECV)(ADDRESS_IP_RECV),
link(UDP-SENDTO)(ADDRESS_UDP_SENDTO)
link(UDP-SENDTO)(ADDRESS_UDP_SENDTO),
link(UNIX-SENDTO)(ADDRESS_UNIX_SENDTO)
label(ADDRESS_INTERFACE)dit(bf(tt(INTERFACE:<interface>)))
Communicates with a network connected on an interface using raw packets
@ -403,7 +403,7 @@ label(ADDRESS_INTERFACE)dit(bf(tt(INTERFACE:<interface>)))
the network interface. Currently only available on Linux.
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET) nl()
Useful options:
link(pf)(OPTION_PROTOCOL_FAMILY)nl()
link(pf)(OPTION_PROTOCOL_FAMILY),
link(type)(OPTION_SO_TYPE)nl()
See also: link(ip-recv)(ADDRESS_IP_RECV)
label(ADDRESS_IP4_SENDTO)dit(bf(tt(IP4-SENDTO:<host>:<protocol>)))
@ -417,7 +417,7 @@ label(ADDRESS_IP_DATAGRAM)dit(bf(tt(IP-DATAGRAM:<address>:<protocol>)))
Sends outgoing data to the specified address which may in particular be a
broadcast or multicast address. Packets arriving on the local socket are
checked if their source addresses match
eventual link(RANGE)(OPTION_RANGE) or link(TCPWRAP)(OPTION_TCPWRAPPERS)
link(RANGE)(OPTION_RANGE) or link(TCPWRAP)(OPTION_TCPWRAPPERS)
options. This address type can for example be used for implementing
symmetric or asymmetric broadcast or multicast communications.nl()
Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET),
@ -444,19 +444,21 @@ label(ADDRESS_IP_DATAGRAM)dit(bf(tt(IP-DATAGRAM:<address>:<protocol>)))
label(ADDRESS_IP4_DATAGRAM)dit(bf(tt(IP4-DATAGRAM:<host>:<protocol>)))
Like link(IP-DATAGRAM)(ADDRESS_IP_DATAGRAM), but always uses IPv4.
(link(example)(EXAMPLE_ADDRESS_IP4_BROADCAST_CLIENT))nl()
Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET),
link(IP4)(GROUP_IP4), link(RANGE)(GROUP_RANGE) nl()
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(RANGE)(GROUP_RANGE) nl()
label(ADDRESS_IP6_DATAGRAM)dit(bf(tt(IP6-DATAGRAM:<host>:<protocol>)))
Like link(IP-DATAGRAM)(ADDRESS_IP_DATAGRAM), but always uses IPv6. Please
note that IPv6 does not know broadcasts.nl()
Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET),
link(IP6)(GROUP_IP6), link(RANGE)(GROUP_RANGE) nl()
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6),link(RANGE)(GROUP_RANGE) nl()
label(ADDRESS_IP_RECVFROM)dit(bf(tt(IP-RECVFROM:<protocol>)))
Opens a raw IP socket of link(<protocol>)(TYPE_PROTOCOL). Depending on option link(pf)(OPTION_PROTOCOL_FAMILY), IP procotol version
4 or 6 is used. It receives one packet from an unspecified peer and may send one or more answer packets to that peer.
This mode is particularly useful with fork option where each arriving packet - from arbitrary peers - is handled by its own sub process.
This allows a behaviour similar to typical UDP based servers like ntpd or named.
This allows a behaviour similar to typical UDP based servers like ntpd or
named.nl()
Please note that the reply packets might be fetched as incoming traffic when
sender and receiver IP address are identical because there is no port number
to distinguish the sockets.nl()
This address works well with IP-SENDTO address peers (see above).
Protocol 255 uses the raw socket with the IP header being part of the
data.nl()
@ -544,6 +546,7 @@ label(ADDRESS_OPENSSL_CONNECT)dit(bf(tt(OPENSSL:<host>:<port>)))
link(cafile)(OPTION_OPENSSL_CAFILE),
link(capath)(OPTION_OPENSSL_CAPATH),
link(certificate)(OPTION_OPENSSL_CERTIFICATE),
link(key)(OPTION_OPENSSL_KEY),
link(bind)(OPTION_BIND),
link(pf)(OPTION_PROTOCOL_FAMILY),
link(connect-timeout)(OPTION_CONNECT_TIMEOUT),
@ -570,6 +573,7 @@ label(ADDRESS_OPENSSL_LISTEN)dit(bf(tt(OPENSSL-LISTEN:<port>)))
link(cafile)(OPTION_OPENSSL_CAFILE),
link(capath)(OPTION_OPENSSL_CAPATH),
link(certificate)(OPTION_OPENSSL_CERTIFICATE),
link(key)(OPTION_OPENSSL_KEY),
link(fork)(OPTION_FORK),
link(bind)(OPTION_BIND),
link(range)(OPTION_RANGE),
@ -1059,7 +1063,7 @@ label(ADDRESS_UDP_DATAGRAM)dit(bf(tt(UDP-DATAGRAM:<address>:<port>)))
Sends outgoing data to the specified address which may in particular be a
broadcast or multicast address. Packets arriving on the local socket are
checked for the correct remote port and if their source addresses match
eventual link(RANGE)(OPTION_RANGE) or link(TCPWRAP)(OPTION_TCPWRAPPERS)
link(RANGE)(OPTION_RANGE) or link(TCPWRAP)(OPTION_TCPWRAPPERS)
options. This address type can for example be used for implementing
symmetric or asymmetric broadcast or multicast communications.nl()
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(RANGE)(GROUP_RANGE) nl()
@ -1089,13 +1093,11 @@ label(ADDRESS_UDP4_DATAGRAM)dit(bf(tt(UDP4-DATAGRAM:<address>:<port>)))
Like link(UDP-DATAGRAM)(ADDRESS_UDP_DATAGRAM), but only supports IPv4
protocol (link(example1)(EXAMPLE_ADDRESS_UDP4_BROADCAST_CLIENT),
link(example2)(EXAMPLE_ADDRESS_UDP4_MULTICAST)).nl()
Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET),
link(IP4)(GROUP_IP4), link(RANGE)(GROUP_RANGE)
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4), link(RANGE)(GROUP_RANGE)
label(ADDRESS_UDP6_DATAGRAM)dit(bf(tt(UDP6-DATAGRAM:<address>:<port>)))
Like link(UDP-DATAGRAM)(ADDRESS_UDP_DATAGRAM), but only supports IPv6
protocol.nl()
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),
link(IP6)(GROUP_IP6),link(RANGE)(GROUP_RANGE)
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6),link(RANGE)(GROUP_RANGE)
label(ADDRESS_UDP_LISTEN)dit(bf(tt(UDP-LISTEN:<port>)))
Waits for a UDP/IP packet arriving on <port>
[link(UDP service)(TYPE_UDP_SERVICE)] and `connects' back to sender.
@ -1167,7 +1169,7 @@ label(ADDRESS_UDP_RECVFROM)dit(bf(tt(UDP-RECVFROM:<port>)))
option
where each arriving packet - from arbitrary peers - is handled by its own sub
process. This allows a behaviour similar to typical UDP based servers like ntpd
or named. This address works well with socat() SENDTO address peers.nl()
or named. This address works well with socat() UDP-SENDTO address peers.nl()
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) nl()
Useful options:
link(fork)(OPTION_FORK),
@ -1228,9 +1230,7 @@ label(ADDRESS_UNIX_CONNECT)dit(bf(tt(UNIX-CONNECT:<filename>)))
if <filename> is not a unixdomain() socket, this is an error;
if <filename> is a unixdomain() socket, but no process is listening, this is
an error.nl()
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),
link(NAMED)(GROUP_NAMED),link(RETRY)(GROUP_RETRY),
link(UNIX)(GROUP_SOCK_UNIX) nl())
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(NAMED)(GROUP_NAMED),link(RETRY)(GROUP_RETRY),link(UNIX)(GROUP_SOCK_UNIX) nl())
Useful options:
link(bind)(OPTION_BIND)nl()
See also:
@ -1247,10 +1247,7 @@ label(ADDRESS_UNIX_LISTEN)dit(bf(tt(UNIX-LISTEN:<filename>)))
Note that opening this address usually blocks until a client connects.
Beginning with socat() version 1.4.3, the file system entry is removed when
this address is closed (but see option link(unlink-close)(OPTION_UNLINK_CLOSE)) (link(example)(EXAMPLE_ADDRESS_UNIX_LISTEN)).nl()
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),
link(NAMED)(GROUP_NAMED),link(LISTEN)(GROUP_LISTEN),
link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY),
link(UNIX)(GROUP_SOCK_UNIX) nl()
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(NAMED)(GROUP_NAMED),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY),link(UNIX)(GROUP_SOCK_UNIX) nl()
Useful options:
link(fork)(OPTION_FORK),
link(umask)(OPTION_UMASK),
@ -1267,7 +1264,11 @@ label(ADDRESS_UNIX_LISTEN)dit(bf(tt(UNIX-LISTEN:<filename>)))
label(ADDRESS_UNIX_SENDTO)dit(bf(tt(UNIX-SENDTO:<filename>)))
Communicates with the specified peer socket, defined by [link(<filename>)(TYPE_FILENAME)] assuming it is a unixdomain() datagram socket.
It sends packets to and receives packets from that peer socket only.
It works well with socat() UNIX-RECVFROM and UNIX-RECV address peers.nl()
Please note that it might be neccessary to link(bind)(OPTION_BIND) the
local socket to an address (e.g. tt(/tmp/sock1), which must not exist
before).
This address type works well with socat() UNIX-RECVFROM and UNIX-RECV address
peers.nl()
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),
link(NAMED)(GROUP_NAMED),link(UNIX)(GROUP_SOCK_UNIX)nl()
Useful options:
@ -1301,8 +1302,7 @@ label(ADDRESS_UNIX_RECV)dit(bf(tt(UNIX-RECV:<filename>)))
Receives packets from multiple unspecified peers and merges the data.
No replies are possible. It can be, e.g., addressed by socat() UNIX-SENDTO address peers.
It behaves similar to a syslog server.
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),
link(NAMED)(GROUP_NAMED),link(UNIX)(GROUP_SOCK_UNIX) nl()
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(NAMED)(GROUP_NAMED),link(UNIX)(GROUP_SOCK_UNIX) nl()
See also:
link(UNIX-SENDTO)(ADDRESS_UNIX_SENDTO),
link(UNIX-RECVFROM)(ADDRESS_UNIX_RECVFROM),
@ -1315,8 +1315,7 @@ label(ADDRESS_UNIX_CLIENT)dit(bf(tt(UNIX-CLIENT:<filename>)))
[link(<filename>)(TYPE_FILENAME)] assuming it is a unixdomain() socket.
It first tries to connect and, if that fails, assumes it is a datagram
socket, thus supporting both types.nl()
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),
link(NAMED)(GROUP_NAMED),link(UNIX)(GROUP_SOCK_UNIX) nl()
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(NAMED)(GROUP_NAMED),link(UNIX)(GROUP_SOCK_UNIX) nl()
Useful options:
link(bind)(OPTION_BIND)nl()
See also:
@ -1544,6 +1543,25 @@ label(OPTION_END_CLOSE)dit(bf(tt(end-close)))
Similarly, when an address of type EXEC or SYSTEM is ended, socat() usually
will explicitely kill the sub process. With this option, it will just close
the file descriptors.
label(OPTION_SHUT_NONE)dit(bf(tt(shut-none)))
Changes the (address dependent) method of shutting down the write part of a
connection to not do anything.
label(OPTION_SHUT_DOWN)dit(bf(tt(shut-down)))
Changes the (address dependent) method of shutting down the write part of a
connection to tt(shutdown\(fd, SHUT_WR)). Is only useful with sockets.
label(OPTION_SHUT_CLOSE)dit(bf(tt(shut-close)))
Changes the (address dependent) method of shutting down the write part of a
connection to tt(close\(fd)).
label(OPTION_SHUT_NULL)dit(bf(tt(shut-null)))
When one address indicates EOF, socat() will send a zero sized packet to the
write channel of the other address to transfer the EOF condition. This is
useful with UDP and other datagram protocols. Has been tested against
netcat and socat with option link(null-eof)(OPTION_NULL_EOF).
label(OPTION_NULL_EOF)dit(bf(tt(null-eof)))
Normally socat() will ignore empty (zero size payload) packets arriving on
datagram sockets, so it survives port scans. With this option socat()
interprets empty datagram packets as EOF indicator (see
link(shut-null)(OPTION_SHUT_NULL).
label(OPTION_IOCTL_VOID)dit(bf(tt(ioctl-void=<request>)))
Calls tt(ioctl()) with the request value as second argument and NULL as
third argument. This option allows to utilize ioctls that are not
@ -1673,21 +1691,24 @@ startdit()
label(OPTION_SEEK)dit(bf(tt(seek=<offset>)))
Applies the code(lseek(fd, <offset>, SEEK_SET)) (or code(lseek64)) system
call, thus positioning the file pointer absolutely to <offset>
[link(off_t)(TYPE_OFF) or link(off64_t)(TYPE_OFF64)].
[link(off_t)(TYPE_OFF) or link(off64_t)(TYPE_OFF64)]. Please note that a
missing value defaults to 1, not 0.
label(OPTION_SEEK_CUR)dit(bf(tt(seek-cur=<offset>)))
Applies the code(lseek(fd, <offset>, SEEK_CUR)) (or code(lseek64)) system
call, thus positioning the file pointer <offset> [link(off_t)(TYPE_OFF) or
link(off64_t)(TYPE_OFF64)] bytes relatively to its current position (which
is usually 0).
is usually 0). Please note that a missing value defaults to 1, not 0.
label(OPTION_SEEK_END)dit(bf(tt(seek-end=<offset>)))
Applies the code(lseek(fd, <offset>, SEEK_END)) (or code(lseek64)) system
call, thus positioning the file pointer <offset> [link(off_t)(TYPE_OFF) or
link(off64_t)(TYPE_OFF64)] bytes relatively to the files current end.
link(off64_t)(TYPE_OFF64)] bytes relatively to the files current end. Please
note that a missing value defaults to 1, not 0.
label(OPTION_FTRUNCATE)dit(bf(tt(ftruncate=<offset>)))
Applies the code(ftruncate(fd, <offset>))
(or code(ftruncate64) if available) system call, thus
truncating the file at the position <offset> [link(off_t)(TYPE_OFF) or
link(off64_t)(TYPE_OFF64)].
link(off64_t)(TYPE_OFF64)]. Please note that a missing value defaults to 1,
not 0.
label(OPTION_EXT2_SECRM_FL)dit(bf(tt(secrm=<bool>)))
label(OPTION_EXT2_UNRM)dit(bf(tt(unrm=<bool>)))
@ -1726,16 +1747,18 @@ label(OPTION_CHROOT_EARLY)dit(bf(tt(chroot-early=<directory>)))
before opening the address. This call might require root privilege.
label(OPTION_SETGID)dit(bf(tt(setgid=<group>)))
Changes the primary link(<group>)(TYPE_GROUP) of the process after
processing the address. This call might require root privilege.
processing the address. This call might require root privilege. Please note
that this option does not drop other group related privileges.
label(OPTION_SETGID_EARLY)dit(bf(tt(setgid-early=<group>)))
Changes the primary link(<group>)(TYPE_GROUP) of the process before opening
the address. This call might require root privilege.
Like link(setgit)(OPTION_SETGID) but is performed before opening the address.
label(OPTION_SETUID)dit(bf(tt(setuid=<user>)))
Changes the link(<user>)(TYPE_USER) (owner) of the process after processing
the address. This call might require root privilege.
the address. This call might require root privilege. Please note that this
option does not drop group related privileges. Check if option
link(su)(OPTION_SUBSTUSER) better fits your needs.
label(OPTION_SETUID_EARLY)dit(bf(tt(setuid-early=<user>)))
Changes the link(<user>)(TYPE_USER) (owner) of the process before opening
the address. This call might require root privilege.
Like link(setuid)(OPTION_SETUID) but is performed before opening the
address.
label(OPTION_SUBSTUSER)dit(bf(tt(su=<user>)))
Changes the link(<user>)(TYPE_USER) (owner) and groups of the process after
processing the address (link(example)(EXAMPLE_OPTION_SUBSTUSER)). This call might require root privilege.
@ -1835,7 +1858,7 @@ label(OPTION_BIND)dit(bf(tt(bind=<sockname>)))
label(OPTION_CONNECT_TIMEOUT)dit(bf(tt(connect-timeout=<seconds>)))
Abort the connection attempt after <seconds> [link(timeval)(TYPE_TIMEVAL)]
with error status.
label(OPTION_INTERFACE)dit(bf(tt(interface=<interface>)))
label(OPTION_SO_BINDTODEV)dit(bf(tt(so-bindtodev=<interface>)))
Binds the socket to the given link(<interface>)(TYPE_INTERFACE).
This option might require root privilege.
label(OPTION_SO_BROADCAST)dit(bf(tt(broadcast)))
@ -2420,7 +2443,7 @@ label(OPTION_FDOUT)dit(bf(tt(fdout=<fdnum>)))
instead of stdout (1). The program started from the subprocess has to use
this fd for writing data to socat() (link(example)(EXAMPLE_OPTION_FDOUT)).
label(OPTION_SIGHUP)label(OPTION_SIGINT)label(OPTION_SIGQUIT)dit(bf(tt(sighup)), bf(tt(sigint)), bf(tt(sigquit)))
Has socat() pass an eventual signal of this type to the sub process.
Has socat() pass signals of this type to the sub process.
If no address has this option, socat() terminates on these signals.
enddit()
@ -3327,7 +3350,7 @@ servers), and the original client request.
label(EXAMPLE_ANCILLARY)
dit(bf(tt(socat -d -d -%UDP4-RECVFROM:9999,so-broadcast,so-timestamp,ip-pktinfo,ip-recverr,ip-recvopts,ip-recvtos,ip-recvttl SYSTEM:'export; sleep 1' |grep SOCAT)))
waits for incoming UDP packets on port 9999 and prints the environment
waits for an incoming UDP packet on port 9999 and prints the environment
variables provided by socat. On BSD based systems you have to replace
link(tt(ip-pktinfo))(OPTION_IP_PKTINFO) with link(tt(ip-recvdstaddr))(OPTION_IP_RECVDSTADDR),link(tt(ip-recvif))(OPTION_IP_RECVIF). Especially interesting is
SOCAT_IP_DSTADDR: it contains the target address of the packet which may be a

View file

@ -1,6 +1,6 @@
#! /bin/sh
# source: mail.sh
# Copyright Gerhard Rieger 2001-2005
# Copyright Gerhard Rieger 2001-2009
# Published under the GNU General Public License V.2, see file COPYING
#set -vx
@ -8,7 +8,9 @@
# This is an example for a shell script that can be fed to socat with exec.
# Its clue is that it does not use stdin/stdout for communication with socat,
# so you may feed the mail message via stdin to the script. The message should
# contain appropriate mail headers.
# contain appropriate mail headers without continuation lines.
# socat establishes the connection to the SMTP server; the script performs the
# SMTP dialog and afterwards transfers the message body to the server.
# Lines with only a dot are not permitted - use two dots as escape.
# This script supports multiline answers from server, but not much more yet.

View file

@ -1,6 +1,6 @@
%define majorver 1.7
%define minorver 0.0
%define minorver 1.0
Summary: socat - multipurpose relay
Name: socat

View file

@ -1,5 +1,5 @@
/* source: sysincludes.h */
/* Copyright Gerhard Rieger 2001-2008 */
/* Copyright Gerhard Rieger 2001-2009 */
/* Published under the GNU General Public License V.2, see file COPYING */
#ifndef __sysincludes_h_included
@ -36,7 +36,7 @@
#if HAVE_GRP_H
#include <grp.h> /* getgrnam() */
#endif
#if HAVE_PTY_H && _WITH_TERMIOS
#if HAVE_PTY_H && (_WITH_TERMIOS || HAVE_OPENPTY)
#include <pty.h>
#endif
#if HAVE_SYS_PARAM_H

238
test.sh
View file

@ -2108,7 +2108,7 @@ waitfile () {
# generate a test certificate and key
gentestcert () {
local name="$1"
if [ -f $name.key -a -f $name.crt -a -f $name.pem ]; then return; fi
if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi
openssl genrsa $OPENSSL_RAND -out $name.key 768 >/dev/null 2>&1
openssl req -new -config testcert.conf -key $name.key -x509 -days 3653 -out $name.crt >/dev/null 2>&1
cat $name.key $name.crt >$name.pem
@ -2118,9 +2118,7 @@ gentestcert () {
gentestdsacert () {
#set -vx
local name="$1"
if [ -f $name.key -a -f $name.crt -a -f $name.pem ]; then
return;
fi
if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi
openssl dsaparam -out $name-dsa.pem 512 >/dev/null 2>&1
openssl dhparam -dsaparam -out $name-dh.pem 512 >/dev/null 2>&1
openssl req -newkey dsa:$name-dsa.pem -keyout $name.key -nodes -x509 -days 3653 -config testcert.conf -out $name.crt >/dev/null 2>&1
@ -2299,14 +2297,13 @@ esac
N=$((N+1))
## LATER:
#NAME=SYSTEMPIPESFLUSH
#case "$TESTS" in
#*%functions%*|*%system%*|*%$NAME%*)
#TEST="$NAME: call to od via system() with pipes"
#testod "$N" "$TEST" "" "system:$OD_C,pipes" "$opts"
#esac
#N=$((N+1))
NAME=SYSTEMPIPESFLUSH
case "$TESTS" in
*%functions%*|*%system%*|*%$NAME%*)
TEST="$NAME: call to od via system() with pipes"
testod "$N" "$TEST" "" "system:$OD_C,pipes" "$opts" "$val_t"
esac
N=$((N+1))
## LATER:
@ -2339,24 +2336,22 @@ N=$((N+1))
#N=$((N+1))
## LATER:
#NAME=SYSTEMPIPESFDSFLUSH
#case "$TESTS" in
#*%functions%*|*%system%*|*%$NAME%*)
#TEST="$NAME: call to od via system() with pipes, non stdio"
#testod "$N" "$TEST" "" "system:$OD_C>&9 <&8,pipes,fdin=8,fdout=9" "$opts"
#esac
#N=$((N+1))
NAME=SYSTEMPIPESFDSFLUSH
case "$TESTS" in
*%functions%*|*%system%*|*%$NAME%*)
TEST="$NAME: call to od via system() with pipes, non stdio"
testod "$N" "$TEST" "" "system:$OD_C>&9 <&8,pipes,fdin=8,fdout=9" "$opts" "$val_t"
esac
N=$((N+1))
## LATER:
#NAME=DUALSYSTEMFDSFLUSH
#case "$TESTS" in
#*%functions%*|*%system%*|*%$NAME%*)
#TEST="$NAME: call to od via dual system()"
#testecho "$N" "$TEST" "system:$CAT<&7,fdin=7%system:$OD_C>&6,fdout=6" "" "$opts"
#esac
#N=$((N+1))
NAME=DUALSYSTEMFDSFLUSH
case "$TESTS" in
*%functions%*|*%system%*|*%$NAME%*)
TEST="$NAME: call to od via dual system()"
testod "$N" "$TEST" "system:$CAT<&7,fdin=7%system:$OD_C>&6,fdout=6" "pipe" "$opts" "$val_t"
esac
N=$((N+1))
case "$UNAME" in
@ -4717,7 +4712,7 @@ case "$TESTS" in
TEST="$NAME: readline with password and sigint"
if ! eval $NUMCOND; then :;
elif ! feat=$(testaddrs readline pty); then
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
else
SAVETERM="$TERM"; TERM= # 'cause konsole might print controls even in raw
@ -4861,7 +4856,7 @@ case "$TESTS" in
TEST="$NAME: gender changer via SSL through HTTP proxy, oneshot"
if ! eval $NUMCOND; then :;
elif ! feat=$(testaddrs openssl proxy); then
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat |tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
else
gentestcert testsrv
@ -4948,7 +4943,7 @@ case "$TESTS" in
TEST="$NAME: gender changer via SSL through HTTP proxy, daemons"
if ! eval $NUMCOND; then :;
elif ! feat=$(testaddrs openssl proxy); then
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
else
gentestcert testsrv
@ -5823,10 +5818,10 @@ case "$TESTS" in
TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection"
if ! eval $NUMCOND; then :; else
if ! feat=$(testaddrs pty); then
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then
$PRINTF "test $F_n $TEST... ${YELLOW}option $(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
$PRINTF "test $F_n $TEST... ${YELLOW}option $(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
else
testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts"
@ -5842,10 +5837,10 @@ case "$TESTS" in
TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection"
if ! eval $NUMCOND; then :;
elif ! feat=$(testaddrs pty); then
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then
$PRINTF "test $F_n $TEST... ${YELLOW}option $(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
$PRINTF "test $F_n $TEST... ${YELLOW}option $(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
else
testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts"
@ -5856,14 +5851,14 @@ N=$((N+1))
NAME=CONNECTTIMEOUT
case "$TESTS" in
*%functions%*|*%$NAME%*)
*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%timeout%*|*%$NAME%*)
TEST="$NAME: test the connect-timeout option"
if ! eval $NUMCOND; then :;
elif ! feat=$(testaddrs tcp); then
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
elif ! feat=$(testoptions connect-timeout); then
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
else
# we need a hanging connection attempt, guess an address for this
@ -5907,6 +5902,53 @@ esac
N=$((N+1))
# version 1.7.0.0 had a bug with the connect-timeout option: while it correctly
# terminated a hanging connect attempt, it prevented a successful connection
# establishment from being recognized by socat, instead the timeout occurred
NAME=CONNECTTIMEOUT_CONN
if ! eval $NUMCOND; then :; else
case "$TESTS" in
*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%timeout%*|*%$NAME%*)
TEST="$NAME: TCP4 connect-timeout option when server replies"
# just try a connection that is expected to succeed with the usual data
# transfer; with the bug it will fail
tf="$td/test$N.stdout"
te="$td/test$N.stderr"
tdiff="$td/test$N.diff"
tsl=$PORT
ts="127.0.0.1:$tsl"
da="test$N $(date) $RANDOM"
CMD1="$SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr PIPE"
CMD2="$SOCAT $opts STDIO TCP4:$ts,connect-timeout=1"
printf "test $F_n $TEST... " $N
$CMD1 >"$tf" 2>"${te}1" &
pid1=$!
waittcp4port $tsl 1
echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
if [ $? -ne 0 ]; then
$PRINTF "$FAILED: $SOCAT:\n"
echo "$CMD1 &"
cat "${te}1"
echo "$CMD2"
cat "${te}2"
numFAIL=$((numFAIL+1))
elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
$PRINTF "$FAILED\n"
cat "$tdiff"
numFAIL=$((numFAIL+1))
else
$PRINTF "$OK\n"
if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
numOK=$((numOK+1))
fi
kill $pid1 2>/dev/null
wait ;;
esac
PORT=$((PORT+1))
fi # NUMCOND
N=$((N+1))
NAME=OPENSSLLISTENDSA
case "$TESTS" in
*%functions%*|*%chain%*|*%openssl%*|*%tcp%*|*%$NAME%*)
@ -5957,7 +5999,7 @@ N=$((N+1))
signum () {
if [ ! "$BASH_VERSION" -o -o posix ]; then
# we expect:
for i in $(POSIXLY_CORRECT=1 kill -l); do echo $i; done |grep -n -i "^$1$" |cut -d: -f1
for i in $(POSIXLY_CORRECT=1 kill -l); do echo "$i"; done |grep -n -i "^$1$" |cut -d: -f1
else
# expect:
# " 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL"
@ -5977,7 +6019,7 @@ case "$TESTS" in
TEST="$NAME: exit status when dying on SIG$signam"
if ! eval $NUMCOND; then :;
elif ! feat=$(testaddrs pty); then
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat |tr a-z A-Z) not available${NORMAL}\n" $N
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr a-z A-Z) not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
else
SIG="$(signum $signam)"
@ -6021,7 +6063,7 @@ case "$TESTS" in
TEST="$NAME: restrict reading from file with bytes option"
if ! eval $NUMCOND; then :;
elif false; then
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
else
tr="$td/test$N.ref"
@ -7672,6 +7714,89 @@ esac
N=$((N+1))
# up to 1.7.0.0 option end-close led to an error with some address types due to
# bad internal handling. here we check it for address PTY
NAME=PTYENDCLOSE
case "$TESTS" in
*%functions%*|*%bugs%*|*%pty%*|*%$NAME%*)
TEST="$NAME: PTY handles option end-close"
# with the bug, socat exits with error. we invoke socat in a no-op mode and
# check its return status.
if ! eval $NUMCOND; then :;
else
tf="$td/test$N.stout"
te="$td/test$N.stderr"
CMD="$SOCAT $opts /dev/null pty,end-close"
printf "test $F_n $TEST... " $N
$CMD 2>"${te}"
rc=$?
if [ "$rc" = 0 ]; then
$PRINTF "$OK\n"
numOK=$((numOK+1))
else
$PRINTF "$FAILED\n"
echo "$CMD"
cat "${te}"
numFAIL=$((numFAIL+1))
fi
fi # NUMCOND
;;
esac
N=$((N+1))
# test the shut-null and null-eof options
NAME=SHUTNULLEOF
case "$TESTS" in
*%functions%*|*%socket%*|*%$NAME%*)
TEST="$NAME: options shut-null and null-eof"
# run a receiving background process with option null-eof.
# start a sending process with option shut-null that sends a test record to the
# receiving process and then terminates.
# send another test record.
# whe the receiving process just got the first test record the test succeeded
if ! eval $NUMCOND; then :; else
tf="$td/test$N.stout"
te="$td/test$N.stderr"
tdiff="$td/test$N.diff"
da="test$N $(date) $RANDOM"
CMD0="$SOCAT $opts -u UDP-RECV:$PORT,null-eof CREAT:$tf"
CMD1="$SOCAT $opts -u - UDP-SENDTO:127.0.0.1:$PORT,shut-null"
printf "test $F_n $TEST... " $N
$CMD0 >/dev/null 2>"${te}0" &
pid0=$!
waitudp4port $PORT 1
echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
rc1=$?
echo "xyz" |$CMD1 >"${tf}2" 2>"${te}2"
rc2=$?
kill $pid0 2>/dev/null; wait
if [ $rc1 != 0 -o $rc2 != 0 ]; then
$PRINTF "$FAILED\n"
echo "$CMD0 &"
echo "$CMD1"
cat "${te}0"
cat "${te}1"
cat "${te}2"
numFAIL=$((numFAIL+1))
elif echo "$da" |diff - "${tf}" >"$tdiff"; then
$PRINTF "$OK\n"
numOK=$((numOK+1))
else
$PRINTF "$FAILED\n"
echo "$CMD0 &"
echo "$CMD1"
cat "${te}0"
cat "${te}1"
cat "${tdiff}"
numFAIL=$((numFAIL+1))
fi
fi # NUMCOND
;;
esac
N=$((N+1))
NAME=UDP6LISTENBIND
# this tests for a bug in (up to) 1.5.0.0:
# with udp*-listen, the bind option supported only IPv4
@ -8016,7 +8141,8 @@ waitip4proto $ts1p 1
usleep $((10*MICROS))
echo "$da" |$CMD2 2>>"${te}2"
rc2="$?"
usleep $((10*MICROS))
#usleep $MICROS
sleep 1
kill "$pid1" 2>/dev/null; wait;
if [ "$rc2" -ne 0 ]; then
$PRINTF "$FAILED: $SOCAT:\n"
@ -8467,7 +8593,7 @@ TEST="$NAME: socat handles data buffered by openssl"
# transferred, the test has failed.
if ! eval $NUMCOND; then :;
elif ! feat=$(testaddrs openssl) >/dev/null; then
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
else
tf="$td/test$N.out"
@ -8519,7 +8645,7 @@ TEST="$NAME: trigger EOF after that many bytes, even when socket idle"
# the process did not terminate and the bug is still there.
if ! eval $NUMCOND; then :;
elif false; then
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
else
tr="$td/test$N.ref"
@ -9106,8 +9232,8 @@ while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_TYPE SCM_NAME ROOT SCM_VA
do
if [ -z "$PF" ] || [[ "$PF" == \#* ]]; then continue; fi
#
pf="$(echo $PF |tr A-Z a-z)"
proto="$(echo $KEYW |tr A-Z a-z)"
pf="$(echo "$PF" |tr A-Z a-z)"
proto="$(echo "$KEYW" |tr A-Z a-z)"
NAME=${KEYW}SCM_$SCM_TYPE
case "$TESTS" in
*%functions%*|*%$pf%*|*%dgram%*|*%udp%*|*%$proto%*|*%recv%*|*%ancillary%*|*%$ROOT%*|*%$NAME%*)
@ -9227,7 +9353,7 @@ IP6 IP6 [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS
while read KEYW FEAT TEST_SOCKADDR TEST_PEERADDR TEST_SOCKPORT TEST_PEERPORT; do
if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
#
test_proto="$(echo $KEYW |tr A-Z a-z)"
test_proto="$(echo "$KEYW" |tr A-Z a-z)"
NAME=${KEYW}LISTENENV
case "$TESTS" in
*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$test_proto%*|*%envvar%*|*%$NAME%*)
@ -9238,12 +9364,12 @@ TEST="$NAME: $KEYW-LISTEN fills environment variables with socket addresses"
# describing the peer and local sockets.
if ! eval $NUMCOND; then :;
elif ! feat=$(testaddrs $FEAT); then
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat |tr a-z A-Z) not available${NORMAL}\n" $N
$PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr a-z A-Z) not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
else
tf="$td/test$N.stdout"
te="$td/test$N.stderr"
TEST_SOCKADDR="$(echo $TEST_SOCKADDR |sed "s/\$N/$N/g")" # actual vars
TEST_SOCKADDR="$(echo "$TEST_SOCKADDR" |sed "s/\$N/$N/g")" # actual vars
tsa="$TEST_SOCKADDR" # test server address
tsp="$TEST_SOCKPORT" # test server port
if [ "$tsp" != ',' ]; then
@ -9251,7 +9377,7 @@ if [ "$tsp" != ',' ]; then
else
tsa1="$tsa"; tsa2= # tsa1 used for addr parameter
fi
TEST_PEERADDR="$(echo $TEST_PEERADDR |sed "s/\$N/$N/g")" # actual vars
TEST_PEERADDR="$(echo "$TEST_PEERADDR" |sed "s/\$N/$N/g")" # actual vars
tca="$TEST_PEERADDR" # test client address
tcp="$TEST_PEERPORT" # test client port
if [ "$tcp" != ',' ]; then
@ -9297,11 +9423,11 @@ else
cat "${te}1"
numFAIL=$((numFAIL+1))
fi
set +xv
fi # NUMCOND, feats
;;
esac
N=$((N+1))
set +xv
#
done <<<"
TCP4 TCP $LOCALHOST $SECONDADDR $PORT $((PORT+1))
@ -9320,8 +9446,8 @@ while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_ENVNAME ROOT SCM_VALUE
do
if [ -z "$PF" ] || [[ "$PF" == \#* ]]; then continue; fi
#
pf="$(echo $PF |tr A-Z a-z)"
proto="$(echo $KEYW |tr A-Z a-z)"
pf="$(echo "$PF" |tr A-Z a-z)"
proto="$(echo "$KEYW" |tr A-Z a-z)"
NAME=${KEYW}ENV_$SCM_ENVNAME
case "$TESTS" in
*%functions%*|*%$pf%*|*%dgram%*|*%udp%*|*%$proto%*|*%recv%*|*%ancillary%*|*%envvar%*|*%$ROOT%*|*%$NAME%*)
@ -10032,7 +10158,7 @@ printf "test $F_n $TEST... " $N
$CMD1 >"$tf" 2>"${te}1" &
pid1=$!
waitsctp4port $tsl 1
# SCTP does not seem to support half close, so we let it 1s to finish
# SCTP does not seem to support half close, so we give it 1s to finish
(echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2"
if [ $? -ne 0 ]; then
$PRINTF "$FAILED: $SOCAT:\n"
@ -10421,12 +10547,12 @@ case "$TESTS" in
TEST="$NAME: give a one line description of test"
# describe how the test is performed, and what's the success criteria
if ! eval $NUMCOND; then :; else
tf="$td/test$N.stout"
tf="$td/test$N.stdout"
te="$td/test$N.stderr"
tdiff="$td/test$N.diff"
da="test$N $(date) $RANDOM"
CMD0="$SOCAT $opts server-address PIPE"
CMD1="$SOCAT - client-address"
CMD1="$SOCAT $opts - client-address"
printf "test $F_n $TEST... " $N
$CMD0 >/dev/null 2>"${te}0" &
pid0=$!

View file

@ -1,5 +1,5 @@
/* source: utils.c */
/* Copyright Gerhard Rieger 2001-2008 */
/* Copyright Gerhard Rieger 2001-2009 */
/* Published under the GNU General Public License V.2, see file COPYING */
/* useful additions to C library */
@ -75,7 +75,7 @@ int setenv(const char *name, const char *value, int overwrite) {
if (!overwrite) {
if (getenv(name)) return 0; /* already exists */
}
if ((env = Malloc(strlen(name)+strlen(value)+2)) != NULL) {
if ((env = Malloc(strlen(name)+strlen(value)+2)) == NULL) {
return -1;
}
sprintf(env, "%s=%s", name, value);

View file

@ -75,9 +75,10 @@ const struct optdesc opt_cool_write = { "cool-write", "coolwrite", OPT_COOL_WRIT
/* control closing of connections */
const struct optdesc opt_end_close = { "end-close", "close", OPT_END_CLOSE, GROUP_FD, PH_INIT, TYPE_CONST, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.howtoclose, XIOCLOSE_CLOSE };
const struct optdesc opt_shut_none = { "shut-none", NULL, OPT_SHUT_NONE, GROUP_FD, PH_INIT, TYPE_CONST, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.howtoshut, XIOSHUT_NONE };
const struct optdesc opt_shut_down = { "shut-down", NULL, OPT_SHUT_DOWN, GROUP_FD, PH_INIT, TYPE_CONST, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.howtoshut, XIOSHUT_DOWN };
const struct optdesc opt_shut_close= { "shut-close", NULL, OPT_SHUT_CLOSE, GROUP_FD, PH_INIT, TYPE_CONST, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.howtoshut, XIOSHUT_CLOSE };
const struct optdesc opt_shut_none = { "shut-none", NULL, OPT_SHUT_NONE, GROUP_FD, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.howtoshut, XIOSHUT_NONE };
const struct optdesc opt_shut_down = { "shut-down", NULL, OPT_SHUT_DOWN, GROUP_FD, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.howtoshut, XIOSHUT_DOWN };
const struct optdesc opt_shut_close= { "shut-close", NULL, OPT_SHUT_CLOSE, GROUP_FD, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.howtoshut, XIOSHUT_CLOSE };
const struct optdesc opt_shut_null = { "shut-null", NULL, OPT_SHUT_NULL, GROUP_FD, PH_INIT, TYPE_CONST, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.howtoshut, XIOSHUT_NULL };
/****** generic ioctl() options ******/
const struct optdesc opt_ioctl_void = { "ioctl-void", "ioctl", OPT_IOCTL_VOID, GROUP_FD, PH_FD, TYPE_INT, OFUNC_IOCTL_GENERIC, 0, 0, 0 };

View file

@ -1,5 +1,5 @@
/* source: xio-fd.h */
/* Copyright Gerhard Rieger 2001-2008 */
/* Copyright Gerhard Rieger 2001-2009 */
/* Published under the GNU General Public License V.2, see file COPYING */
#ifndef __xio_fd_h_included
@ -45,6 +45,7 @@ extern const struct optdesc opt_end_close;
extern const struct optdesc opt_shut_none;
extern const struct optdesc opt_shut_down;
extern const struct optdesc opt_shut_close;
extern const struct optdesc opt_shut_null;
extern const struct optdesc opt_streams_i_push;
#endif /* !defined(__xio_fd_h_included) */

View file

@ -1,5 +1,5 @@
/* source: xio-listen.c */
/* Copyright Gerhard Rieger 2001-2008 */
/* Copyright Gerhard Rieger 2001-2009 */
/* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for listen socket options */
@ -261,8 +261,10 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl
la = NULL;
}
Notice2("accepting connection from %s on %s",
sockaddr_info(pa?&pa->soa:NULL, pas, peername, sizeof(peername)),
sockaddr_info(pa?&la->soa:NULL, las, sockname, sizeof(sockname)));
pa?
sockaddr_info(&pa->soa, pas, peername, sizeof(peername)):"NULL",
la?
sockaddr_info(&la->soa, las, sockname, sizeof(sockname)):"NULL");
if (pa != NULL && la != NULL && xiocheckpeer(xfd, pa, la) < 0) {
if (Shutdown(ps, 2) < 0) {
@ -271,6 +273,7 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl
continue;
}
if (pa != NULL)
Info1("permitting connection from %s",
sockaddr_info((struct sockaddr *)pa, pas,
infobuff, sizeof(infobuff)));
@ -331,8 +334,8 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl
return result;
/* set the env vars describing the local and remote sockets */
xiosetsockaddrenv("SOCK", la, las, proto);
xiosetsockaddrenv("PEER", pa, pas, proto);
if (la != NULL) xiosetsockaddrenv("SOCK", la, las, proto);
if (pa != NULL) xiosetsockaddrenv("PEER", pa, pas, proto);
return 0;
}

View file

@ -1,5 +1,5 @@
/* source: xio-process.c */
/* Copyright Gerhard Rieger 2001-2003 */
/* Copyright Gerhard Rieger 2001-2009 */
/* Published under the GNU General Public License V.2, see file COPYING */
/* this file handles process related addresses options */
@ -14,6 +14,7 @@ const struct optdesc opt_setgid_early= { "setgid-early",NULL, OPT_SETGID_EARLY,
const struct optdesc opt_setgid = { "setgid", NULL, OPT_SETGID, GROUP_PROCESS, PH_LATE2, TYPE_GIDT, OFUNC_SPEC };
const struct optdesc opt_setuid_early= { "setuid-early",NULL, OPT_SETUID_EARLY,GROUP_PROCESS, PH_EARLY, TYPE_UIDT, OFUNC_SPEC };
const struct optdesc opt_setuid = { "setuid", NULL, OPT_SETUID, GROUP_PROCESS, PH_LATE2, TYPE_UIDT, OFUNC_SPEC };
const struct optdesc opt_substuser_early = { "substuser-early", "su-e", OPT_SUBSTUSER_EARLY, GROUP_PROCESS, PH_EARLY, TYPE_UIDT, OFUNC_SPEC };
const struct optdesc opt_substuser = { "substuser", "su", OPT_SUBSTUSER, GROUP_PROCESS, PH_LATE2, TYPE_UIDT, OFUNC_SPEC };
const struct optdesc opt_substuser_delayed = { "substuser-delayed", "su-d", OPT_SUBSTUSER_DELAYED, GROUP_PROCESS, PH_INIT, TYPE_UIDT, OFUNC_SPEC };
const struct optdesc opt_chroot_early = { "chroot-early", NULL, OPT_CHROOT_EARLY, GROUP_PROCESS, PH_EARLY, TYPE_STRING, OFUNC_SPEC };

View file

@ -1,5 +1,5 @@
/* source: xio-process.h */
/* Copyright Gerhard Rieger 2001, 2002 */
/* Copyright Gerhard Rieger 2001-2009 */
/* Published under the GNU General Public License V.2, see file COPYING */
#ifndef __xio_process_h_included
@ -9,6 +9,7 @@ extern const struct optdesc opt_setgid_early;
extern const struct optdesc opt_setgid;
extern const struct optdesc opt_setuid_early;
extern const struct optdesc opt_setuid;
extern const struct optdesc opt_substuser_early;
extern const struct optdesc opt_substuser;
extern const struct optdesc opt_substuser_delayed;
extern const struct optdesc opt_chroot_early;

View file

@ -40,7 +40,7 @@ const struct optdesc opt_pipes = { "pipes", NULL, OPT_PIPES, GROUP_F
#if HAVE_PTY
const struct optdesc opt_pty = { "pty", NULL, OPT_PTY, GROUP_FORK, PH_BIGEN, TYPE_BOOL, OFUNC_SPEC };
#endif
const struct optdesc opt_commtype= { "commtype", "c", OPT_COMMTYPE, GROUP_FORK, PH_BIGEN, TYPE_STRING, OFUNC_SPEC };
const struct optdesc opt_commtype= { "commtype", NULL, OPT_COMMTYPE, GROUP_FORK, PH_BIGEN, TYPE_STRING, OFUNC_SPEC };
const struct optdesc opt_stderr = { "stderr", NULL, OPT_STDERR, GROUP_FORK, PH_PASTFORK, TYPE_BOOL, OFUNC_SPEC };
const struct optdesc opt_nofork = { "nofork", NULL, OPT_NOFORK, GROUP_FORK, PH_BIGEN, TYPE_BOOL, OFUNC_SPEC };
const struct optdesc opt_sighup = { "sighup", NULL, OPT_SIGHUP, GROUP_PARENT, PH_LATE, TYPE_CONST, OFUNC_SIGNAL, SIGHUP };
@ -87,7 +87,7 @@ int _xioopen_progcall(int xioflags, /* XIO_RDONLY etc. */
struct opt *popts; /* parent process options */
int numleft;
int sv[2], rdpip[2], wrpip[2];
int saverfd, savewfd; /* with inter addr, save assigned right fds */
int saverfd = -1, savewfd = -1; /* with inter addr, save assigned right fds */
int rw = (xioflags & XIO_ACCMODE);
char *commname;
int commtype = XIOCOMM_SOCKETPAIRS;
@ -213,6 +213,7 @@ int _xioopen_progcall(int xioflags, /* XIO_RDONLY etc. */
case XIOCOMM_TCP4: typename = "TCP4 socket pair"; break;
case XIOCOMM_TCP4_LISTEN: typename = "TCP4 listen socket pair"; break;
#endif
default: typename = NULL; break;
}
Notice2("forking off child, using %s for %s",
typename, ddirection[rw]);
@ -758,6 +759,7 @@ Warn1("xio-progcall.c: fd->howtoshut == %d", fd->howtoshut);
}
if (fdi != sv[1] && fdo != sv[1]) {
applyopts_cloexec(sv[1], *copts);
Close(sv[1]);
}
applyopts(fdi, *copts, PH_LATE);

View file

@ -1,5 +1,5 @@
/* source: xio-pty.c */
/* Copyright Gerhard Rieger 2002-2008 */
/* Copyright Gerhard Rieger 2002-2009 */
/* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for creating pty addresses */
@ -66,8 +66,8 @@ static int xioopen_pty(const char *linkname, struct opt *opts, int xioflags, xio
compatibility we choose "no" as default */
struct timespec pollintv = { PTY_INTERVALL };
applyopts(-1, opts, PH_INIT);
if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1;
applyopts(-1, opts, PH_INIT);
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
@ -99,8 +99,8 @@ static int xioopen_pty(const char *linkname, struct opt *opts, int xioflags, xio
retropt_timespec(opts, OPT_PTY_INTERVALL, &pollintv);
#endif /* HAVE_POLL */
applyopts2(-1, opts, PH_INIT, PH_EARLY);
if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1;
applyopts2(-1, opts, PH_INIT, PH_EARLY);
applyopts(-1, opts, PH_PREBIGEN);

View file

@ -226,6 +226,8 @@ const struct optdesc opt_setsockopt_int = { "setsockopt-int", "sockopt-int
const struct optdesc opt_setsockopt_bin = { "setsockopt-bin", "sockopt-bin", OPT_SETSOCKOPT_BIN, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_BIN, OFUNC_SOCKOPT_GENERIC, 0, 0 };
const struct optdesc opt_setsockopt_string = { "setsockopt-string", "sockopt-string", OPT_SETSOCKOPT_STRING, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_STRING, OFUNC_SOCKOPT_GENERIC, 0, 0 };
const struct optdesc opt_null_eof = { "null-eof", NULL, OPT_NULL_EOF, GROUP_SOCKET, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.para.socket.null_eof };
#if WITH_GENERICSOCKET
@ -267,8 +269,8 @@ int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts,
retropt_int(opts, OPT_SO_TYPE, &socktype);
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
applyopts(-1, opts, PH_INIT);
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
applyopts(-1, opts, PH_INIT);
applyopts(-1, opts, PH_EARLY);
themlen = 0;
@ -891,10 +893,10 @@ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen,
themlen, strerror(errno));
timeout = xfd->para.socket.connect_timeout;
writefd.fd = xfd->rfd;
writefd.events = (POLLIN|POLLHUP|POLLERR);
writefd.events = (POLLOUT|POLLERR);
result = xiopoll(&writefd, 1, &timeout);
if (result < 0) {
Msg4(level, "xiopoll({%d,POLLIN|POLLHUP|POLLER},,{"F_tv_sec"."F_tv_usec"): %s",
Msg4(level, "xiopoll({%d,POLLOUT|POLLER},,{"F_tv_sec"."F_tv_usec"): %s",
xfd->rfd, timeout.tv_sec, timeout.tv_usec, strerror(errno));
return STAT_RETRYLATER;
}
@ -904,7 +906,7 @@ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen,
strerror(ETIMEDOUT));
return STAT_RETRYLATER;
}
if (writefd.revents & POLLOUT) {
if (writefd.revents & POLLERR) {
#if 0
unsigned char dummy[1];
Read(xfd->rfd, &dummy, 1); /* get error message */

View file

@ -1,5 +1,5 @@
/* source: xio-socket.h */
/* Copyright Gerhard Rieger 2001-2008 */
/* Copyright Gerhard Rieger 2001-2009 */
/* Published under the GNU General Public License V.2, see file COPYING */
#ifndef __xio_socket_h_included
@ -67,6 +67,7 @@ extern const struct optdesc opt_protocol_family;
extern const struct optdesc opt_setsockopt_int;
extern const struct optdesc opt_setsockopt_bin;
extern const struct optdesc opt_setsockopt_string;
extern const struct optdesc opt_null_eof;
extern

View file

@ -169,6 +169,7 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
}
}
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
applyopts(-1, opts, PH_INIT);
applyopts(-1, opts, PH_EARLY);
@ -242,8 +243,8 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
xfd->opt_unlink_close = true;
}
applyopts(-1, opts, PH_INIT);
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
applyopts(-1, opts, PH_INIT);
applyopts(-1, opts, PH_EARLY);
if ((result =
@ -315,8 +316,8 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i
xfd->opt_unlink_close = true;
}
applyopts(-1, opts, PH_INIT);
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
applyopts(-1, opts, PH_INIT);
if ((result =
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
@ -497,8 +498,8 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups,
struct opt *opts0;
int result;
applyopts(-1, opts, PH_INIT);
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
applyopts(-1, opts, PH_INIT);
retropt_socket_pf(opts, &pf);

4
xio.h
View file

@ -123,11 +123,13 @@ struct opt;
#define XIOSHUTRD_SIGTERM 0x0050 /* kill sub process with SIGTERM */
#define XIOSHUTWR_SIGTERM 0x0005 /* kill sub process with SIGTERM */
#define XIOSHUTWR_SIGKILL 0x0006 /* kill sub process with SIGKILL */
#define XIOSHUTWR_NULL 0x0007 /* send empty packet (dgram socket) */
#define XIOSHUT_UNSPEC (XIOSHUTRD_UNSPEC|XIOSHUTWR_UNSPEC)
#define XIOSHUT_NONE (XIOSHUTRD_NONE|XIOSHUTWR_NONE)
#define XIOSHUT_CLOSE (XIOSHUTRD_CLOSE|XIOSHUTWR_CLOSE)
#define XIOSHUT_DOWN (XIOSHUTRD_DOWN|XIOSHUTWR_DOWN)
#define XIOSHUT_KILL (XIOSHUTRD_KILL|XIOSHUTWR_KILL)
#define XIOSHUT_NULL (XIOSHUTRD_DOWN|XIOSHUTWR_NULL)
#define XIOSHUT_PTYEOF 0x0100 /* change pty to icanon and write VEOF */
#define XIOSHUT_OPENSSL 0x0101 /* specific action on openssl */
/*!!!*/
@ -374,7 +376,7 @@ typedef struct single {
struct {
struct timeval connect_timeout; /* how long to hang in connect() */
union sockaddr_union la; /* local socket address */
bool emptyiseof; /* with dgram: empty packet means EOF */
bool null_eof; /* with dgram: empty packet means EOF */
bool dorange;
struct xiorange range; /* restrictions for peer address */
#if _WITH_IP4 || _WITH_IP6

View file

@ -1,5 +1,5 @@
/* source: xiohelp.c */
/* Copyright Gerhard Rieger 2001-2008 */
/* Copyright Gerhard Rieger 2001-2009 */
/* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for the help function */

View file

@ -937,6 +937,8 @@ const struct optname optionnames[] = {
#ifdef O_NSHARE
IF_OPEN ("nshare", &opt_o_nshare)
#endif
IF_SOCKET ("null-eof", &opt_null_eof)
IF_ANY ("o-append", &opt_append)
#ifdef O_ASYNC
IF_ANY ("o-async", &opt_async)
#endif
@ -1286,6 +1288,7 @@ const struct optname optionnames[] = {
IF_ANY ("shut-close", &opt_shut_close)
IF_ANY ("shut-down", &opt_shut_down)
IF_ANY ("shut-none", &opt_shut_none)
IF_ANY ("shut-null", &opt_shut_null)
#if WITH_EXEC || WITH_SYSTEM
IF_ANY ("sid", &opt_setsid)
#endif
@ -1428,8 +1431,10 @@ const struct optname optionnames[] = {
#endif
IF_ANY ("su", &opt_substuser)
IF_ANY ("su-d", &opt_substuser_delayed)
IF_ANY ("su-e", &opt_substuser_early)
IF_ANY ("substuser", &opt_substuser)
IF_ANY ("substuser-delayed", &opt_substuser_delayed)
IF_ANY ("substuser-early", &opt_substuser_early)
IF_TERMIOS("susp", &opt_vsusp)
#ifdef VSWTC
IF_TERMIOS("swtc", &opt_vswtc)
@ -3256,6 +3261,7 @@ int applyopts(int fd, struct opt *opts, enum e_phase phase) {
opt->desc = ODESC_ERROR; ++opt; continue;
}
break;
case OPT_SUBSTUSER_EARLY:
case OPT_SUBSTUSER:
{
struct passwd *pwd;

View file

@ -448,6 +448,7 @@ enum e_optcode {
OPT_NOFLSH, /* termios.c_lflag */
OPT_NOFORK, /* exec, system */
OPT_NOPROMPT, /* readline */
OPT_NULL_EOF, /* receiving empty packet triggers EOF */
#ifdef OCRNL
OPT_OCRNL, /* termios.c_oflag */
#endif
@ -600,6 +601,7 @@ enum e_optcode {
OPT_SHUT_CLOSE,
OPT_SHUT_DOWN,
OPT_SHUT_NONE,
OPT_SHUT_NULL, /* send 0 bytes on shutdown */
OPT_SIGHUP,
OPT_SIGINT,
OPT_SIGQUIT,
@ -707,6 +709,7 @@ enum e_optcode {
# define ENABLE_OPTCODE
# include "xio-streams.h"
# undef ENABLE_OPTCODE
OPT_SUBSTUSER_EARLY,
OPT_SUBSTUSER,
OPT_SUBSTUSER_DELAYED,
OPT_SYMBOLIC_LINK, /* with pty */

View file

@ -1,5 +1,5 @@
/* source: xioread.c */
/* Copyright Gerhard Rieger 2001-2008 */
/* Copyright Gerhard Rieger 2001-2009 */
/* Published under the GNU General Public License V.2, see file COPYING */
/* this is the source of the extended read function */
@ -189,7 +189,7 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) {
bytes,
sockaddr_info(&from.soa, fromlen, infobuff, sizeof(infobuff)));
if (bytes == 0) {
if (!pipe->para.socket.emptyiseof) {
if (!pipe->para.socket.null_eof) {
errno = EAGAIN; return -1;
}
return bytes;
@ -380,7 +380,7 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) {
bytes,
sockaddr_info(&from.soa, fromlen, infobuff, sizeof(infobuff)));
if (bytes == 0) {
if (!pipe->para.socket.emptyiseof) {
if (!pipe->para.socket.null_eof) {
errno = EAGAIN; return -1;
}
return bytes;

View file

@ -1,5 +1,5 @@
/* source: xioshutdown.c */
/* Copyright Gerhard Rieger 2001-2008 */
/* Copyright Gerhard Rieger 2001-2009 */
/* Published under the GNU General Public License V.2, see file COPYING */
/* this is the source of the extended shutdown function */
@ -20,6 +20,7 @@ static void signal_kill_pid(int dummy) {
/* how: SHUT_RD, SHUT_WR, or SHUT_RDWR */
int xioshutdown(xiofile_t *sock, int how) {
int fd;
int result = 0;
Debug2("xioshutdown(%p, %d)", sock, how);
@ -43,6 +44,8 @@ int xioshutdown(xiofile_t *sock, int how) {
return result;
}
fd = XIO_GETWRFD(sock);
/* let us bring how nearer to the resulting action */
if ((sock->stream.flags&XIO_ACCMODE) == XIO_WRONLY) {
how = ((how+1) & ~(SHUT_RD+1)) - 1;
@ -50,7 +53,6 @@ int xioshutdown(xiofile_t *sock, int how) {
how = ((how+1) & ~(SHUT_WR+1)) - 1;
}
/* here handle special shutdown functions */
switch (sock->stream.howtoshut) {
#if WITH_PTY
case XIOSHUT_PTYEOF:
@ -92,6 +94,31 @@ int xioshutdown(xiofile_t *sock, int how) {
/*! what about half/full close? */
return 0;
#endif /* WITH_OPENSSL */
default:
break;
}
/* here handle special shutdown functions */
switch (sock->stream.howtoshut & XIOSHUTWR_MASK) {
char writenull;
case XIOSHUTWR_NONE:
return 0;
case XIOSHUTWR_CLOSE:
if (Close(fd) < 0) {
Info2("close(%d): %s", fd, strerror(errno));
}
return 0;
case XIOSHUTWR_DOWN:
if ((result = Shutdown(fd, how)) < 0) {
Info3("shutdown(%d, %d): %s", fd, how, strerror(errno));
}
return 0;
#if _WITH_SOCKET
case XIOSHUTWR_NULL:
/* send an empty packet; only useful on datagram sockets? */
xiowrite(sock, &writenull, 0);
return 0;
#endif /* _WITH_SOCKET */
default: break;
}
@ -103,25 +130,23 @@ int xioshutdown(xiofile_t *sock, int how) {
switch (sock->stream.howtoshut) {
#if _WITH_SOCKET
case XIOSHUT_DOWN:
if ((result = Shutdown(sock->stream.fd1, how)) < 0) {
Info3("shutdown(%d, %d): %s",
sock->stream.fd1, how, strerror(errno));
if ((result = Shutdown(fd, how)) < 0) {
Info3("shutdown(%d, %d): %s", fd, how, strerror(errno));
}
break;
case XIOSHUT_KILL:
if ((result = Shutdown(sock->stream.fd1, how)) < 0) {
Info3("shutdown(%d, %d): %s",
sock->stream.fd1, how, strerror(errno));
if ((result = Shutdown(fd, how)) < 0) {
Info3("shutdown(%d, %d): %s", fd, how, strerror(errno));
}
break;
#endif /* _WITH_SOCKET */
case XIOSHUT_CLOSE:
Close(sock->stream.fd1);
Close(fd);
#if WITH_TERMIOS
if (sock->stream.ttyvalid) {
if (Tcsetattr(sock->stream.fd1, 0, &sock->stream.savetty) < 0) {
if (Tcsetattr(fd, 0, &sock->stream.savetty) < 0) {
Warn2("cannot restore terminal settings on fd %d: %s",
sock->stream.fd1, strerror(errno));
fd, strerror(errno));
}
}
#endif /* WITH_TERMIOS */
@ -136,9 +161,9 @@ int xioshutdown(xiofile_t *sock, int how) {
#if 0 && _WITH_SOCKET
case XIODATA_RECVFROM:
if (how >= 1) {
if (Close(sock->stream.fd1) < 0) {
if (Close(fd) < 0) {
Info2("close(%d): %s",
sock->stream.fd1, strerror(errno));
fd, strerror(errno));
}
sock->stream.eof = 2;
sock->stream.fd1 = -1;
@ -154,9 +179,8 @@ int xioshutdown(xiofile_t *sock, int how) {
case XIOREAD_STREAM:
case XIODATA_2PIPE:
if (Close(sock->stream.rfd) < 0) {
Info2("close(%d): %s",
sock->stream.rfd, strerror(errno));
if (Close(fd) < 0) {
Info2("close(%d): %s", fd, strerror(errno));
}
break;
}
@ -164,9 +188,6 @@ int xioshutdown(xiofile_t *sock, int how) {
if ((how+1) & 2) { /* contains SHUT_WR */
/* shutdown write channel */
int fd;
fd = sock->stream.wfd;
switch (sock->stream.howtoshut & XIOSHUTWR_MASK) {

View file

@ -247,8 +247,8 @@ int xiosocketpair2(int pf, int socktype, int protocol, int sv[2]) {
int xiocommpair(int commtype, bool lefttoright, bool righttoleft,
int dual, xiofd_t *left, xiofd_t *right, ...) {
va_list ap;
int domain, socktype, protocol;
int useptmx;
int domain = -1, socktype = -1, protocol = -1;
int useptmx = 0;
/* arrays can be used with pipe(2) and socketpair(2): */
int svlr[2] = {-1, -1}; /* left to right: rfd, wfd */
int svrl[2] = {-1, -1}; /* right to left: rfd, wfd */