mirror of
https://github.com/moparisthebest/socat
synced 2024-12-21 22:48:48 -05:00
new address option "escape" allows to break a socat instance
This commit is contained in:
parent
d70b8963aa
commit
c86345a615
4
CHANGES
4
CHANGES
@ -1,4 +1,8 @@
|
|||||||
|
|
||||||
|
new features:
|
||||||
|
new address option "escape" allows to break a socat instance even when
|
||||||
|
raw terminal mode prevents ^C etc.
|
||||||
|
|
||||||
corrections:
|
corrections:
|
||||||
some raw IP and UNIX datagram modes failed on BSD systems
|
some raw IP and UNIX datagram modes failed on BSD systems
|
||||||
|
|
||||||
|
2
VERSION
2
VERSION
@ -1 +1 @@
|
|||||||
"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock"
|
"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+escape"
|
||||||
|
18
doc/socat.yo
18
doc/socat.yo
@ -10,7 +10,7 @@ def(Filan)(0)(bf(Filan))
|
|||||||
def(procan)(0)(bf(procan))
|
def(procan)(0)(bf(procan))
|
||||||
def(Procan)(0)(bf(Procan))
|
def(Procan)(0)(bf(Procan))
|
||||||
|
|
||||||
manpage(socat)(1)(Feb 2008)(socat)()
|
manpage(socat)(1)(Jul 2008)(socat)()
|
||||||
|
|
||||||
whenhtml(
|
whenhtml(
|
||||||
label(CONTENTS)
|
label(CONTENTS)
|
||||||
@ -1516,6 +1516,10 @@ label(OPTION_LOCKFILE)dit(bf(tt(lockfile=<filename>)))
|
|||||||
label(OPTION_WAITLOCK)dit(bf(tt(waitlock=<filename>)))
|
label(OPTION_WAITLOCK)dit(bf(tt(waitlock=<filename>)))
|
||||||
If lockfile exists, waits until it disappears. When lockfile does not exist,
|
If lockfile exists, waits until it disappears. When lockfile does not exist,
|
||||||
creates it and continues, unlinks lockfile on exit.
|
creates it and continues, unlinks lockfile on exit.
|
||||||
|
label(OPTION_ESCAPE)dit(bf(tt(escape=<int>)))
|
||||||
|
Specifies the numeric code of a character that triggers EOF on the input
|
||||||
|
stream. It is useful with a terminal in raw mode
|
||||||
|
(link(example)(EXAMPLE_OPTION_ESCAPE)).
|
||||||
enddit()
|
enddit()
|
||||||
|
|
||||||
startdit()enddit()nl()
|
startdit()enddit()nl()
|
||||||
@ -2630,13 +2634,15 @@ at most 512 data bytes per packet (link(mss)(OPTION_MSS)).
|
|||||||
label(EXAMPLE_ADDRESS_GOPEN)
|
label(EXAMPLE_ADDRESS_GOPEN)
|
||||||
label(EXAMPLE_OPTION_RAW)
|
label(EXAMPLE_OPTION_RAW)
|
||||||
label(EXAMPLE_OPTION_ECHO)
|
label(EXAMPLE_OPTION_ECHO)
|
||||||
dit(bf(tt(socat - /dev/ttyS0,raw,echo=0,crnl)))
|
label(EXAMPLE_OPTION_ESCAPE)
|
||||||
|
dit(bf(tt(socat -,raw,echo=0,escape=0x0f /dev/ttyS0,raw,echo=0,crnl)))
|
||||||
|
|
||||||
Opens an interactive connection via the serial line, e.g. for talking with a
|
Opens an interactive connection via the serial line, e.g. for talking with a
|
||||||
modem. link(raw)(OPTION_RAW) and link(echo)(OPTION_ECHO) set ttyS0's terminal
|
modem. link(raw)(OPTION_RAW) and link(echo)(OPTION_ECHO) set the console's and
|
||||||
parameters to practicable values, link(crnl)(OPTION_CRNL)
|
ttyS0's terminal parameters to practicable values, link(crnl)(OPTION_CRNL)
|
||||||
converts to correct newline characters. Consider using
|
converts to correct newline characters. link(escape)(OPTION_ESCAPE) allows to
|
||||||
link(READLINE)(ADDRESS_READLINE) instead of `-'.
|
terminate the socat process with character control-O.
|
||||||
|
Consider using link(READLINE)(ADDRESS_READLINE) instead of the first address.
|
||||||
|
|
||||||
|
|
||||||
label(EXAMPLE_ADDRESS_UNIX_LISTEN)
|
label(EXAMPLE_ADDRESS_UNIX_LISTEN)
|
||||||
|
70
socat.c
70
socat.c
@ -948,6 +948,10 @@ int _socat(void) {
|
|||||||
/* avoid idle when all readbytes already there */
|
/* avoid idle when all readbytes already there */
|
||||||
mayrd1 = true;
|
mayrd1 = true;
|
||||||
}
|
}
|
||||||
|
/* escape char occurred? */
|
||||||
|
if (XIO_RDSTREAM(sock1)->actescape) {
|
||||||
|
bytes1 = 0; /* indicate EOF */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* (bytes1 == 0) handled later */
|
/* (bytes1 == 0) handled later */
|
||||||
} else {
|
} else {
|
||||||
@ -976,6 +980,10 @@ int _socat(void) {
|
|||||||
/* avoid idle when all readbytes already there */
|
/* avoid idle when all readbytes already there */
|
||||||
mayrd2 = true;
|
mayrd2 = true;
|
||||||
}
|
}
|
||||||
|
/* escape char occurred? */
|
||||||
|
if (XIO_RDSTREAM(sock2)->actescape) {
|
||||||
|
bytes2 = 0; /* indicate EOF */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* (bytes2 == 0) handled later */
|
/* (bytes2 == 0) handled later */
|
||||||
} else {
|
} else {
|
||||||
@ -988,7 +996,8 @@ int _socat(void) {
|
|||||||
bytes1, XIO_RDSTREAM(sock1)->eof, XIO_RDSTREAM(sock1)->ignoreeof,
|
bytes1, XIO_RDSTREAM(sock1)->eof, XIO_RDSTREAM(sock1)->ignoreeof,
|
||||||
closing);*/
|
closing);*/
|
||||||
if (bytes1 == 0 || XIO_RDSTREAM(sock1)->eof >= 2) {
|
if (bytes1 == 0 || XIO_RDSTREAM(sock1)->eof >= 2) {
|
||||||
if (XIO_RDSTREAM(sock1)->ignoreeof && !closing) {
|
if (XIO_RDSTREAM(sock1)->ignoreeof &&
|
||||||
|
!XIO_RDSTREAM(sock1)->actescape && !closing) {
|
||||||
Debug1("socket 1 (fd %d) is at EOF, ignoring",
|
Debug1("socket 1 (fd %d) is at EOF, ignoring",
|
||||||
XIO_RDSTREAM(sock1)->fd); /*! */
|
XIO_RDSTREAM(sock1)->fd); /*! */
|
||||||
mayrd1 = true;
|
mayrd1 = true;
|
||||||
@ -996,16 +1005,20 @@ int _socat(void) {
|
|||||||
} else {
|
} else {
|
||||||
Notice1("socket 1 (fd %d) is at EOF", XIO_GETRDFD(sock1));
|
Notice1("socket 1 (fd %d) is at EOF", XIO_GETRDFD(sock1));
|
||||||
xioshutdown(sock2, SHUT_WR);
|
xioshutdown(sock2, SHUT_WR);
|
||||||
|
XIO_RDSTREAM(sock1)->eof = 2;
|
||||||
|
XIO_RDSTREAM(sock1)->ignoreeof = false;
|
||||||
if (socat_opts.lefttoright) {
|
if (socat_opts.lefttoright) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
closing = 1;
|
||||||
}
|
}
|
||||||
} else if (polling && XIO_RDSTREAM(sock1)->ignoreeof) {
|
} else if (polling && XIO_RDSTREAM(sock1)->ignoreeof) {
|
||||||
polling = 0;
|
polling = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes2 == 0 || XIO_RDSTREAM(sock2)->eof >= 2) {
|
if (bytes2 == 0 || XIO_RDSTREAM(sock2)->eof >= 2) {
|
||||||
if (XIO_RDSTREAM(sock2)->ignoreeof && !closing) {
|
if (XIO_RDSTREAM(sock2)->ignoreeof &&
|
||||||
|
!XIO_RDSTREAM(sock2)->actescape && !closing) {
|
||||||
Debug1("socket 2 (fd %d) is at EOF, ignoring",
|
Debug1("socket 2 (fd %d) is at EOF, ignoring",
|
||||||
XIO_RDSTREAM(sock2)->fd);
|
XIO_RDSTREAM(sock2)->fd);
|
||||||
mayrd2 = true;
|
mayrd2 = true;
|
||||||
@ -1013,9 +1026,12 @@ int _socat(void) {
|
|||||||
} else {
|
} else {
|
||||||
Notice1("socket 2 (fd %d) is at EOF", XIO_GETRDFD(sock2));
|
Notice1("socket 2 (fd %d) is at EOF", XIO_GETRDFD(sock2));
|
||||||
xioshutdown(sock1, SHUT_WR);
|
xioshutdown(sock1, SHUT_WR);
|
||||||
|
XIO_RDSTREAM(sock2)->eof = 2;
|
||||||
|
XIO_RDSTREAM(sock2)->ignoreeof = false;
|
||||||
if (socat_opts.righttoleft) {
|
if (socat_opts.righttoleft) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
closing = 1;
|
||||||
}
|
}
|
||||||
} else if (polling && XIO_RDSTREAM(sock2)->ignoreeof) {
|
} else if (polling && XIO_RDSTREAM(sock2)->ignoreeof) {
|
||||||
polling = 0;
|
polling = 0;
|
||||||
@ -1102,8 +1118,9 @@ static int
|
|||||||
|
|
||||||
/* inpipe is suspected to have read data available; read at most bufsiz bytes
|
/* inpipe is suspected to have read data available; read at most bufsiz bytes
|
||||||
and transfer them to outpipe. Perform required data conversions.
|
and transfer them to outpipe. Perform required data conversions.
|
||||||
buff should be at least twice as large as bufsiz, to allow all standard
|
buff must be a malloc()'ed storage and might be realloc()'ed in this
|
||||||
conversions. Returns the number of bytes written, or 0 on EOF or <0 if an
|
function if more space is required after conversions.
|
||||||
|
Returns the number of bytes written, or 0 on EOF or <0 if an
|
||||||
error occurred or when data was read but none written due to conversions
|
error occurred or when data was read but none written due to conversions
|
||||||
(with EAGAIN). EAGAIN also occurs when reading from a nonblocking FD where
|
(with EAGAIN). EAGAIN also occurs when reading from a nonblocking FD where
|
||||||
the file has a mandatory lock.
|
the file has a mandatory lock.
|
||||||
@ -1113,9 +1130,9 @@ static int
|
|||||||
/* inpipe, outpipe must be single descriptors (not dual!) */
|
/* inpipe, outpipe must be single descriptors (not dual!) */
|
||||||
int xiotransfer(xiofile_t *inpipe, xiofile_t *outpipe,
|
int xiotransfer(xiofile_t *inpipe, xiofile_t *outpipe,
|
||||||
unsigned char **buff, size_t bufsiz, bool righttoleft) {
|
unsigned char **buff, size_t bufsiz, bool righttoleft) {
|
||||||
ssize_t bytes, writt;
|
ssize_t bytes, writt = 0;
|
||||||
|
|
||||||
bytes = xioread(inpipe, *buff, socat_opts.bufsiz);
|
bytes = xioread(inpipe, *buff, bufsiz);
|
||||||
if (bytes < 0) {
|
if (bytes < 0) {
|
||||||
if (errno != EAGAIN)
|
if (errno != EAGAIN)
|
||||||
XIO_RDSTREAM(inpipe)->eof = 2;
|
XIO_RDSTREAM(inpipe)->eof = 2;
|
||||||
@ -1123,14 +1140,35 @@ int xiotransfer(xiofile_t *inpipe, xiofile_t *outpipe,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (bytes == 0 && XIO_RDSTREAM(inpipe)->ignoreeof && !closing) {
|
if (bytes == 0 && XIO_RDSTREAM(inpipe)->ignoreeof && !closing) {
|
||||||
writt = 0;
|
;
|
||||||
} else if (bytes == 0) {
|
} else if (bytes == 0) {
|
||||||
XIO_RDSTREAM(inpipe)->eof = 2;
|
XIO_RDSTREAM(inpipe)->eof = 2;
|
||||||
closing = MAX(closing, 1);
|
closing = MAX(closing, 1);
|
||||||
writt = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else /* if (bytes > 0)*/ {
|
if (bytes > 0) {
|
||||||
|
/* handle escape char */
|
||||||
|
if (XIO_RDSTREAM(inpipe)->escape != -1) {
|
||||||
|
/* check input data for escape char */
|
||||||
|
unsigned char *ptr = *buff;
|
||||||
|
size_t ctr = 0;
|
||||||
|
while (ctr < bytes) {
|
||||||
|
if (*ptr == XIO_RDSTREAM(inpipe)->escape) {
|
||||||
|
/* found: set flag, truncate input data */
|
||||||
|
XIO_RDSTREAM(inpipe)->actescape = true;
|
||||||
|
bytes = ctr;
|
||||||
|
Info("escape char found in input");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++ptr; ++ctr;
|
||||||
|
}
|
||||||
|
if (ctr != bytes) {
|
||||||
|
XIO_RDSTREAM(inpipe)->eof = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes > 0) {
|
||||||
|
|
||||||
if (XIO_RDSTREAM(inpipe)->lineterm !=
|
if (XIO_RDSTREAM(inpipe)->lineterm !=
|
||||||
XIO_WRSTREAM(outpipe)->lineterm) {
|
XIO_WRSTREAM(outpipe)->lineterm) {
|
||||||
@ -1248,8 +1286,14 @@ int xiotransfer(xiofile_t *inpipe, xiofile_t *outpipe,
|
|||||||
#define LF '\n'
|
#define LF '\n'
|
||||||
|
|
||||||
|
|
||||||
int cv_newline(unsigned char **buff, ssize_t *bytes,
|
/* converts the newline characters (or character sequences) from the one
|
||||||
|
specified in lineterm1 to that of lineterm2. Possible values are
|
||||||
|
LINETERM_CR, LINETERM_CRNL, LINETERM_RAW.
|
||||||
|
buff points to the malloc()'ed data, input and output. It may be subject to
|
||||||
|
realloc(). bytes specifies the number of bytes input and output */
|
||||||
|
int cv_newline(unsigned char **buff, ssize_t *bufsiz,
|
||||||
int lineterm1, int lineterm2) {
|
int lineterm1, int lineterm2) {
|
||||||
|
ssize_t *bytes = bufsiz;
|
||||||
/* must perform newline changes */
|
/* must perform newline changes */
|
||||||
if (lineterm1 <= LINETERM_CR && lineterm2 <= LINETERM_CR) {
|
if (lineterm1 <= LINETERM_CR && lineterm2 <= LINETERM_CR) {
|
||||||
/* no change in data length */
|
/* no change in data length */
|
||||||
@ -1287,7 +1331,7 @@ int cv_newline(unsigned char **buff, ssize_t *bytes,
|
|||||||
*t++ = *s++;
|
*t++ = *s++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*bytes = t - *buff;
|
*bufsiz = t - *buff;
|
||||||
} else {
|
} else {
|
||||||
/* buffer becomes longer, must alloc another space */
|
/* buffer becomes longer, must alloc another space */
|
||||||
unsigned char *buf2;
|
unsigned char *buf2;
|
||||||
@ -1297,7 +1341,7 @@ int cv_newline(unsigned char **buff, ssize_t *bytes,
|
|||||||
} else {
|
} else {
|
||||||
from = '\r';
|
from = '\r';
|
||||||
}
|
}
|
||||||
if ((buf2 = Malloc(2*socat_opts.bufsiz+1)) == NULL) {
|
if ((buf2 = Malloc(2*socat_opts.bufsiz/*sic!*/+1)) == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
s = *buff; t = buf2; z = *buff + *bytes;
|
s = *buff; t = buf2; z = *buff + *bytes;
|
||||||
@ -1312,7 +1356,7 @@ int cv_newline(unsigned char **buff, ssize_t *bytes,
|
|||||||
}
|
}
|
||||||
free(*buff);
|
free(*buff);
|
||||||
*buff = buf2;
|
*buff = buf2;
|
||||||
*bytes = t - buf2;;
|
*bufsiz = t - buf2;;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
63
test.sh
63
test.sh
@ -8447,6 +8447,69 @@ esac
|
|||||||
N=$((N+1))
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
|
# test the escape option
|
||||||
|
NAME=ESCAPE
|
||||||
|
case "$TESTS" in
|
||||||
|
*%functions%*|*%escape%*|*%$NAME%*)
|
||||||
|
TEST="$NAME: escape character triggers EOF"
|
||||||
|
# idea: start socat just echoing input, but apply escape option. send a string
|
||||||
|
# containing the escape character and check if the output is truncated
|
||||||
|
tf="$td/test$N.stdout"
|
||||||
|
te="$td/test$N.stderr"
|
||||||
|
tdiff="$td/test$N.diff"
|
||||||
|
da="test$N $(date) $RANDOM"
|
||||||
|
CMD="$SOCAT $opts -,escape=27 pipe"
|
||||||
|
printf "test $F_n $TEST... " $N
|
||||||
|
$ECHO "$da\n\x1bXYZ" |$CMD >"$tf" 2>"$te"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
$PRINTF "$FAILED: $SOCAT:\n"
|
||||||
|
echo "$CMD"
|
||||||
|
cat "$te"
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
|
||||||
|
$PRINTF "$FAILED: diff:\n"
|
||||||
|
cat "$tdiff"
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
else
|
||||||
|
$PRINTF "$OK\n"
|
||||||
|
if [ -n "$debug" ]; then cat $te; fi
|
||||||
|
numOK=$((numOK+1))
|
||||||
|
fi
|
||||||
|
esac
|
||||||
|
N=$((N+1))
|
||||||
|
|
||||||
|
# test the escape option combined with ignoreeof
|
||||||
|
NAME=ESCAPE_IGNOREEOF
|
||||||
|
case "$TESTS" in
|
||||||
|
*%functions%*|*%ignoreeof%*|*%escape%*|*%$NAME%*)
|
||||||
|
TEST="$NAME: escape character triggers EOF"
|
||||||
|
# idea: start socat just echoing input, but apply escape option. send a string
|
||||||
|
# containing the escape character and check if the output is truncated
|
||||||
|
ti="$td/test$N.file"
|
||||||
|
tf="$td/test$N.stdout"
|
||||||
|
te="$td/test$N.stderr"
|
||||||
|
tdiff="$td/test$N.diff"
|
||||||
|
da="test$N $(date) $RANDOM"
|
||||||
|
CMD="$SOCAT -T 5 $opts file:$ti,ignoreeof,escape=27!!- pipe"
|
||||||
|
printf "test $F_n $TEST... " $N
|
||||||
|
>"$ti"
|
||||||
|
$CMD >"$tf" 2>"$te" &
|
||||||
|
$ECHO "$da\n\x1bXYZ" >>"$ti"
|
||||||
|
sleep 1
|
||||||
|
if ! echo "$da" |diff - "$tf" >"$tdiff"; then
|
||||||
|
$PRINTF "$FAILED: diff:\n"
|
||||||
|
cat "$tdiff"
|
||||||
|
cat "$te"
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
else
|
||||||
|
$PRINTF "$OK\n"
|
||||||
|
if [ -n "$debug" ]; then cat $te; fi
|
||||||
|
numOK=$((numOK+1))
|
||||||
|
fi
|
||||||
|
esac
|
||||||
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed"
|
echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed"
|
||||||
|
|
||||||
if [ "$numFAIL" -gt 0 ]; then
|
if [ "$numFAIL" -gt 0 ]; then
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* source: xio-tun.c */
|
/* source: xio-tun.c */
|
||||||
/* Copyright Gerhard Rieger 2007 */
|
/* Copyright Gerhard Rieger 2007-2008 */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||||
|
|
||||||
/* this file contains the source for opening addresses of tun/tap type */
|
/* this file contains the source for opening addresses of tun/tap type */
|
||||||
@ -17,8 +17,6 @@
|
|||||||
|
|
||||||
static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
||||||
|
|
||||||
#define XIO_OFFSETOF(x) ((size_t)&((xiosingle_t *)0)->x)
|
|
||||||
|
|
||||||
/****** TUN addresses ******/
|
/****** TUN addresses ******/
|
||||||
const struct optdesc opt_tun_device = { "tun-device", NULL, OPT_TUN_DEVICE, GROUP_TUN, PH_OPEN, TYPE_FILENAME, OFUNC_SPEC };
|
const struct optdesc opt_tun_device = { "tun-device", NULL, OPT_TUN_DEVICE, GROUP_TUN, PH_OPEN, TYPE_FILENAME, OFUNC_SPEC };
|
||||||
const struct optdesc opt_tun_name = { "tun-name", NULL, OPT_TUN_NAME, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };
|
const struct optdesc opt_tun_name = { "tun-name", NULL, OPT_TUN_NAME, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };
|
||||||
|
2
xio.h
2
xio.h
@ -167,6 +167,8 @@ typedef struct single {
|
|||||||
const char *name; /* only with END_UNLINK */
|
const char *name; /* only with END_UNLINK */
|
||||||
int (*sigchild)(struct single *); /* callback after sigchild */
|
int (*sigchild)(struct single *); /* callback after sigchild */
|
||||||
pid_t ppid; /* parent pid, only if we send it signals */
|
pid_t ppid; /* parent pid, only if we send it signals */
|
||||||
|
int escape; /* escape character; -1 for no escape */
|
||||||
|
bool actescape; /* escape character found in input data */
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
int fdout; /* use fd for output */
|
int fdout; /* use fd for output */
|
||||||
|
@ -16,6 +16,7 @@ const struct optdesc opt_crnl = { "crnl", NULL, OPT_CRNL, GROUP_A
|
|||||||
const struct optdesc opt_readbytes = { "readbytes", "bytes", OPT_READBYTES, GROUP_APPL, PH_LATE, TYPE_SIZE_T, OFUNC_EXT, (int)(&((struct single *)0)->readbytes), sizeof(((struct single *)0)->readbytes) };
|
const struct optdesc opt_readbytes = { "readbytes", "bytes", OPT_READBYTES, GROUP_APPL, PH_LATE, TYPE_SIZE_T, OFUNC_EXT, (int)(&((struct single *)0)->readbytes), sizeof(((struct single *)0)->readbytes) };
|
||||||
const struct optdesc opt_lockfile = { "lockfile", NULL, OPT_LOCKFILE, GROUP_APPL, PH_INIT, TYPE_FILENAME, OFUNC_EXT, 0, 0 };
|
const struct optdesc opt_lockfile = { "lockfile", NULL, OPT_LOCKFILE, GROUP_APPL, PH_INIT, TYPE_FILENAME, OFUNC_EXT, 0, 0 };
|
||||||
const struct optdesc opt_waitlock = { "waitlock", NULL, OPT_WAITLOCK, GROUP_APPL, PH_INIT, TYPE_FILENAME, OFUNC_EXT, 0, 0 };
|
const struct optdesc opt_waitlock = { "waitlock", NULL, OPT_WAITLOCK, GROUP_APPL, PH_INIT, TYPE_FILENAME, OFUNC_EXT, 0, 0 };
|
||||||
|
const struct optdesc opt_escape = { "escape", NULL, OPT_ESCAPE, GROUP_APPL, PH_INIT, TYPE_INT, OFUNC_OFFSET, XIO_OFFSETOF(escape), sizeof(((xiosingle_t *)0)->escape) };
|
||||||
/****** APPL addresses ******/
|
/****** APPL addresses ******/
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
const struct optdesc opt_forever = { "forever", NULL, OPT_FOREVER, GROUP_RETRY, PH_INIT, TYPE_BOOL, OFUNC_EXT, (int)(&((struct single *)0)->forever), sizeof(((struct single *)0)->forever) };
|
const struct optdesc opt_forever = { "forever", NULL, OPT_FOREVER, GROUP_RETRY, PH_INIT, TYPE_BOOL, OFUNC_EXT, (int)(&((struct single *)0)->forever), sizeof(((struct single *)0)->forever) };
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* source: xiolayer.h */
|
/* source: xiolayer.h */
|
||||||
/* Copyright Gerhard Rieger 2001-2005 */
|
/* Copyright Gerhard Rieger 2001-2008 */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||||
|
|
||||||
#ifndef __xiolayer_h_included
|
#ifndef __xiolayer_h_included
|
||||||
@ -11,6 +11,7 @@ extern const struct optdesc opt_crnl;
|
|||||||
extern const struct optdesc opt_readbytes;
|
extern const struct optdesc opt_readbytes;
|
||||||
extern const struct optdesc opt_lockfile;
|
extern const struct optdesc opt_lockfile;
|
||||||
extern const struct optdesc opt_waitlock;
|
extern const struct optdesc opt_waitlock;
|
||||||
|
extern const struct optdesc opt_escape;
|
||||||
extern const struct optdesc opt_forever;
|
extern const struct optdesc opt_forever;
|
||||||
extern const struct optdesc opt_intervall;
|
extern const struct optdesc opt_intervall;
|
||||||
extern const struct optdesc opt_retry;
|
extern const struct optdesc opt_retry;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* source: xioopen.c */
|
/* source: xioopen.c */
|
||||||
/* Copyright Gerhard Rieger 2001-2007 */
|
/* Copyright Gerhard Rieger 2001-2008 */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||||
|
|
||||||
/* this is the source file of the extended open function */
|
/* this is the source file of the extended open function */
|
||||||
@ -301,6 +301,7 @@ static xiofile_t *xioallocfd(void) {
|
|||||||
#endif /* WITH_SOCKET */
|
#endif /* WITH_SOCKET */
|
||||||
fd->stream.howtoend = END_UNSPEC;
|
fd->stream.howtoend = END_UNSPEC;
|
||||||
/* fd->stream.name = NULL; */
|
/* fd->stream.name = NULL; */
|
||||||
|
fd->stream.escape = -1;
|
||||||
/* fd->stream.para.exec.pid = 0; */
|
/* fd->stream.para.exec.pid = 0; */
|
||||||
fd->stream.lineterm = LINETERM_RAW;
|
fd->stream.lineterm = LINETERM_RAW;
|
||||||
|
|
||||||
|
@ -397,6 +397,7 @@ const struct optname optionnames[] = {
|
|||||||
IF_TERMIOS("eol2", &opt_veol2)
|
IF_TERMIOS("eol2", &opt_veol2)
|
||||||
IF_TERMIOS("erase", &opt_verase)
|
IF_TERMIOS("erase", &opt_verase)
|
||||||
IF_SOCKET ("error", &opt_so_error)
|
IF_SOCKET ("error", &opt_so_error)
|
||||||
|
IF_ANY ("escape", &opt_escape)
|
||||||
IF_OPEN ("excl", &opt_o_excl)
|
IF_OPEN ("excl", &opt_o_excl)
|
||||||
#if WITH_EXT2 && defined(EXT2_APPEND_FL)
|
#if WITH_EXT2 && defined(EXT2_APPEND_FL)
|
||||||
IF_ANY ("ext2-append", &opt_ext2_append)
|
IF_ANY ("ext2-append", &opt_ext2_append)
|
||||||
@ -3339,6 +3340,8 @@ static int applyopt_offset(struct single *xfd, struct opt *opt) {
|
|||||||
switch (opt->desc->type) {
|
switch (opt->desc->type) {
|
||||||
case TYPE_BOOL:
|
case TYPE_BOOL:
|
||||||
*(bool *)ptr = opt->value.u_bool; break;
|
*(bool *)ptr = opt->value.u_bool; break;
|
||||||
|
case TYPE_INT:
|
||||||
|
*(int *)ptr = opt->value.u_int; break;
|
||||||
case TYPE_DOUBLE:
|
case TYPE_DOUBLE:
|
||||||
*(double *)ptr = opt->value.u_double; break;
|
*(double *)ptr = opt->value.u_double; break;
|
||||||
case TYPE_TIMEVAL:
|
case TYPE_TIMEVAL:
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#define ODESC_DONE ((void *)-1) /* indicates that option has been applied */
|
#define ODESC_DONE ((void *)-1) /* indicates that option has been applied */
|
||||||
#define ODESC_ERROR ODESC_DONE /* maybe later */
|
#define ODESC_ERROR ODESC_DONE /* maybe later */
|
||||||
|
|
||||||
|
#define XIO_OFFSETOF(x) ((size_t)&((xiosingle_t *)0)->x)
|
||||||
|
|
||||||
/* atomic structure for use in the option search table; keep compatible with
|
/* atomic structure for use in the option search table; keep compatible with
|
||||||
struct wordent! */
|
struct wordent! */
|
||||||
struct optname {
|
struct optname {
|
||||||
@ -250,6 +252,7 @@ enum e_optcode {
|
|||||||
OPT_ECHOPRT, /* termios.c_lflag */
|
OPT_ECHOPRT, /* termios.c_lflag */
|
||||||
#endif
|
#endif
|
||||||
OPT_END_CLOSE, /* xfd.stream.howtoend = END_CLOSE */
|
OPT_END_CLOSE, /* xfd.stream.howtoend = END_CLOSE */
|
||||||
|
OPT_ESCAPE,
|
||||||
OPT_EXT2_SECRM,
|
OPT_EXT2_SECRM,
|
||||||
OPT_EXT2_UNRM,
|
OPT_EXT2_UNRM,
|
||||||
OPT_EXT2_COMPR,
|
OPT_EXT2_COMPR,
|
||||||
|
Loading…
Reference in New Issue
Block a user