Re: [Toybox] [PATCH] tr: fix pathological flushing.
On Sat, Dec 5, 2020, 3:38 AM Rob Landley wrote: > (Also, line buffering sucks because it'll flush at the buffer size anyway > so > you're not guaranteed to get a full line of contiguous output. What it > REALLY > wants is nagle's algorithm for stdout but no libc ever bothered to > IMPLEMENT it, > possibly because of the runtime expense... Ahem. My point is commands > should > probably do sane output blocking on their own.) AFAIK, the only way this would work is if libc only ever does nonblocking writes to stdout, which also means it would need to spawn a thread or use SIGIO to flush its buffer when stdout becomes available, plus modify the flags on STDOUT_FILENO to be O_NONBLOCK (which doesn't even work on regular files). I think people would be far more annoyed with this behavior than any potential gains would justify? (io_uring might make things more interesting, though? You could eliminate libc's buffering entirely, and just memcpy and submit a write for every single fwrite, up to some buffer limit.) ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] llvm regression test.
On Mon, May 4, 2020 at 2:57 PM Rob Landley wrote: > What portion of this script does what when? Right, assuming all the bisect > stuff > is ignorable and the command line editing isn't relevant, where's the real > binary it passes through to? > > $ find clang-r377782d -name clang | xargs file > clang-r377782d/include/clang: directory > clang-r377782d/bin/clang: Python script, ASCII text executable > clang-r377782d/lib64/clang: directory > clang-r377782d/lib64/cmake/clang: directory > clang-r377782d/share/clang: directory > You're looking for "clang.real". ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] [PATCH] losetup: fix the race.
On Wed, Aug 7, 2019 at 8:59 AM enh via Toybox wrote: > iirc, the adb maintainer has similar problems where when you first > connect an Android device to a Linux host, it shows up but with the > wrong permissions which then fix themselves if you wait+retry. which > for my money is even worse. (but maybe not. there are pros and cons > either way, and neither is ideal. and i'm guessing that Ryan's mention > of EACCES means that he's seen that problem with losetup too.) For anyone interested, the race here is that libusb has two implementations for noticing when USB devices are hotplugged, one that listens to udev over dbus, and one that listens to the kernel directly over an AF_NETLINK socket. We use netlink because we can't link against libudev since it isn't API or ABI stable, and that means we get a notification that a device has arrived before udev has gotten a chance to chown/chmod its device node. ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] setenv memory leak.
On Mon, Apr 8, 2019 at 1:12 PM Rob Landley wrote: > Yes, they have to do it themselves because libc is doing it unusably wrong for > anything that persists and changes environment variables repeatedly. > > *shrug* Reinventing this wheel isn't hard, I'd just hoped I wouldn't have to. > But I didn't complain widely enough long ago, and only musl fixed the leak. Shells need to keep track of variables separately from the environment to handle non-exported variables anyway. I suppose you could keep everything in the environment and keep a list of non-exported variables as well, but that just seems like more work for no reason. Making setenv not leak seems impossible in the presence of threaded code, anyway: you have no way of knowing whether the return value of getenv just got freed because some other thread came in and called setenv, so the only solution is basically to just never call setenv (but that fixes your leak, too!). ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] NDK versions?
On Fri, Mar 8, 2019 at 12:34 PM Rob Landley wrote: > > What would be really really nice is if you had -cc and -c++ symlinks to the > latest -clang and -clang++ versions in the zip file. Then I wouldn't have to > create them, so I wouldn't have to work out which version is latest. (You > could > also have some kind of "latest" in there, but... the -cc and -c++ symlinks > _are_ > a "latest" in directly usable format...) > > [puppy eyes intensify] AIUI, symlinks in the NDK are a pain in the ass because of Windows, which required administrative privileges to create until very recently (and windows's built in zip support probably doesn't support symlinks). ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] [PATCH] nc: allow immediate reuse of ports
Whoops, missed that. Another patch attached. On Fri, Jan 25, 2019 at 6:49 AM Rob Landley wrote: > On 1/24/19 7:38 PM, Josh Gao via Toybox wrote: > > Set SO_REUSEADDR when listening so that we can immediately reuse ports > > that are no longer being listened upon, instead of having to wait 60 > > seconds for the socket to be shutdown after being closed (even on > > localhost!). > > This only applies to the else fork when they didn't specify TT.s. Was that > intentional? > > Rob > From b438cf7fe5b88ce085ab745a7d91690be7325ddb Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Fri, 25 Jan 2019 12:50:58 -0800 Subject: [PATCH] xconnbind: allow immediate reuse of ports. --- lib/net.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/net.c b/lib/net.c index 346d17e9..83baed1a 100644 --- a/lib/net.c +++ b/lib/net.c @@ -42,9 +42,20 @@ int xconnbind(struct addrinfo *ai_arg, int dobind) // Try all the returned addresses. Report errors if last entry can't connect. for (ai = ai_arg; ai; ai = ai->ai_next) { +int rc; + fd = (ai->ai_next ? socket : xsocket)(ai->ai_family, ai->ai_socktype, ai->ai_protocol); -if (!(dobind ? bind : connect)(fd, ai->ai_addr, ai->ai_addrlen)) break; + +if (dobind) { + int val = 1; + xsetsockopt(fd, SOL_SOCKET, SO_REUSEADDR, , sizeof(val)); + rc = bind(fd, ai->ai_addr, ai->ai_addrlen); +} else { + rc = connect(fd, ai->ai_addr, ai->ai_addrlen); +} + +if (!rc) break; else if (!ai->ai_next) perror_exit_raw(dobind ? "bind" : "connect"); close(fd); } -- 2.20.1.495.gaa96b0ce6b-goog ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
[Toybox] [PATCH] nc: allow immediate reuse of ports
Set SO_REUSEADDR when listening so that we can immediately reuse ports that are no longer being listened upon, instead of having to wait 60 seconds for the socket to be shutdown after being closed (even on localhost!). From 05be3873b985d8d6f401c6e96f2b99927c41e126 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Thu, 24 Jan 2019 17:32:35 -0800 Subject: [PATCH] nc: allow immediate reuse of ports. Set SO_REUSEADDR when listening so that we can immediately reuse ports that are no longer being listened upon, instead of having to wait 60 seconds for the socket to be shutdown after being closed (even on localhost!). --- toys/net/netcat.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/toys/net/netcat.c b/toys/net/netcat.c index 57304f44..fbf3dca8 100644 --- a/toys/net/netcat.c +++ b/toys/net/netcat.c @@ -144,6 +144,12 @@ void netcat_main(void) } sockfd = xsocket(family, type, 0); + +{ + int val = 1; + xsetsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, , sizeof(val)); +} + if (bind(sockfd, address, bind_addrlen)) perror_exit("bind"); } -- 2.20.1.495.gaa96b0ce6b-goog ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
[Toybox] [PATCH] Fix `netcat -l -p 12345`.
Previously, when trying to listen on a socket without using one of -4, -6, or -s, we tried to create an AF_UNSPEC socket, which fails. --- toys/net/netcat.c | 4 1 file changed, 4 insertions(+) diff --git a/toys/net/netcat.c b/toys/net/netcat.c index 761d1f2a..57304f44 100644 --- a/toys/net/netcat.c +++ b/toys/net/netcat.c @@ -125,6 +125,10 @@ void netcat_main(void) } else { size_t bind_addrlen; +// If we weren't given an address with which to resolve which family to +// use, we have to choose. +if (family == AF_UNSPEC) family = AF_INET; + address->sa_family = family; if (family == AF_INET6) { -- 2.20.1.415.g653613c723-goog ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
[Toybox] [PATCH] nc: IPv6, -4/-6, UDP
I sent some patches to add these a year ago, and the people requesting the functionality probably just hit the same point in their development cycle where they're wanting this again :-) From 0f431a44804920a693e8832dbc784b70f227318a Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Mon, 10 Dec 2018 16:57:46 -0800 Subject: [PATCH 1/2] nc: add IPv6 support. --- lib/lib.h | 1 + lib/net.c | 18 toys/net/netcat.c | 108 -- 3 files changed, 75 insertions(+), 52 deletions(-) diff --git a/lib/lib.h b/lib/lib.h index 14bb7cf6..6dc2ca2b 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -301,6 +301,7 @@ void xsetsockopt(int fd, int level, int opt, void *val, socklen_t len); struct addrinfo *xgetaddrinfo(char *host, char *port, int family, int socktype, int protocol, int flags); int xconnect(struct addrinfo *ai_arg); +int xbind(struct addrinfo *ai_arg); int xpoll(struct pollfd *fds, int nfds, int timeout); int pollinate(int in1, int in2, int out1, int out2, int timeout, int shutdown_timeout); char *ntop(struct sockaddr *sa); diff --git a/lib/net.c b/lib/net.c index 8969306b..880ad89b 100644 --- a/lib/net.c +++ b/lib/net.c @@ -53,6 +53,24 @@ int xconnect(struct addrinfo *ai_arg) return fd; } +int xbind(struct addrinfo *ai_arg) +{ + struct addrinfo *ai; + int fd = -1; + + // Try all the returned addresses. Report errors if last entry can't connect. + for (ai = ai_arg; ai; ai = ai->ai_next) { +fd = (ai->ai_next ? socket : xsocket)(ai->ai_family, ai->ai_socktype, + ai->ai_protocol); +if (!bind(fd, ai->ai_addr, ai->ai_addrlen)) break; +else if (!ai->ai_next) perror_exit("connect"); +close(fd); + } + freeaddrinfo(ai_arg); + + return fd; +} + int xpoll(struct pollfd *fds, int nfds, int timeout) { int i; diff --git a/toys/net/netcat.c b/toys/net/netcat.c index aa251b88..d7dd9264 100644 --- a/toys/net/netcat.c +++ b/toys/net/netcat.c @@ -7,14 +7,16 @@ * netcat -L zombies USE_NETCAT(OLDTOY(nc, netcat, TOYFLAG_USR|TOYFLAG_BIN)) -USE_NETCAT(NEWTOY(netcat, USE_NETCAT_LISTEN("^tlL")"w#<1W#<1p#<1>65535q#<1s:f:"USE_NETCAT_LISTEN("[!tlL][!Lw]"), TOYFLAG_BIN)) +USE_NETCAT(NEWTOY(netcat, USE_NETCAT_LISTEN("^tlL")"w#<1W#<1p#<1>65535q#<1s:f:46"USE_NETCAT_LISTEN("[!tlL][!Lw]")"[!46]", TOYFLAG_BIN)) config NETCAT bool "netcat" default y help -usage: netcat [-u] [-wpq #] [-s addr] {IPADDR PORTNUM|-f FILENAME} +usage: netcat [-46] [-u] [-wpq #] [-s addr] {IPADDR PORTNUM|-f FILENAME} +-4 Force IPv4 +-6 Force IPv6 -f Use FILENAME (ala /dev/ttyS0) instead of network -p Local port number -q Quit SECONDS after EOF on stdin, even if stdout hasn't closed yet @@ -66,35 +68,10 @@ static void set_alarm(int seconds) alarm(seconds); } -// Translate x.x.x.x numeric IPv4 address, or else DNS lookup an IPv4 name. -static void lookup_name(char *name, uint32_t *result) -{ - struct hostent *hostbyname; - - hostbyname = gethostbyname(name); // getaddrinfo - if (!hostbyname) error_exit("no host '%s'", name); - *result = *(uint32_t *)*hostbyname->h_addr_list; -} - -// Worry about a fancy lookup later. -static unsigned short lookup_port(char *str) -{ - struct servent *se; - int i = atoi(str); - - if (i>0 && i<65536) return SWAP_BE16(i); - - se = getservbyname(str, "tcp"); - i = se ? se->s_port : 0; - endservent(); - - return i; -} - void netcat_main(void) { - struct sockaddr_in *address = (void *)toybuf; - int sockfd=-1, in1 = 0, in2 = 0, out1 = 1, out2 = 1; + int sockfd = -1, in1 = 0, in2 = 0, out1 = 1, out2 = 1; + int family = AF_UNSPEC; pid_t child; // Addjust idle and quit_delay to miliseconds or -1 for no timeout @@ -109,30 +86,18 @@ void netcat_main(void) (!(toys.optflags&(FLAG_l|FLAG_L)) && toys.optc!=2)) help_exit("bad argument count"); + if (toys.optflags_4) +family = AF_INET; + else if (toys.optflags_6) +family = AF_INET6; + if (TT.f) in1 = out2 = xopen(TT.f, O_RDWR); else { // Setup socket -sockfd = xsocket(AF_INET, SOCK_STREAM, 0); -setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, , sizeof(out1)); - -address->sin_family = AF_INET; -if (TT.s || TT.p) { - address->sin_port = SWAP_BE16(TT.p); - if (TT.s) -lookup_name(TT.s, (uint32_t *)&(address->sin_addr)); - if (bind(sockfd, (struct sockaddr *)address, sizeof(*address))) -perror_exit("bind"); -} - -// Dial out - if (!(toys.optflags&(FLAG_L|FLAG_l))) { - // Figure out where to dial out to. - lookup_name(*toys.optargs, (uint32_t *)&(address->sin_addr)); - address->sin_port = lookup_port(toys.optargs[1]); -// TODO xconnect - if (connect(sockfd, (struct sockaddr *
Re: [Toybox] Warning: gcc can't tell this is never used uninitialized, but llvm can.
On Tue, Oct 30, 2018 at 10:05 AM Rob Landley wrote: > On 10/30/18 11:40 AM, Rob Landley wrote: > > And the three warnings gcc produces (but llvm doesn't), the larger todo > item for > > which is to figure out what to do about the "int x = x;" stuff, > > Ooh, spoke too soon. The gcc guys _did_ split it up so you can specifically > disable this warning without losing the "is used uninitialized" one. > > (assuming current llvm doesn't barf on the extra flag) > I have bad news for you: $ ./prebuilts/clang/host/linux-x86/clang-r339409b/bin/clang -Wmaybe-initialized -x c++ - warning: unknown warning option '-Wmaybe-initialized'; did you mean '-Wuninitialized'? [-Wunknown-warning-option] ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] ls (/-b/-q) (/on a tty)
On Fri, Dec 8, 2017 at 6:12 PM, Rob Landleywrote: > > I dunno about "wrong", but I agree it's not what ubuntu's does. > Posix-2008 is ambivalent: > > -q Force each instance of non-printable filename characters and >characters to be written as the ( '?' ) > character. Implementations may provide this option by default > if the output is to a terminal device. > POSIX 2008 defines 'printable character' as explicitly including space: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_287 http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01 ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] [PATCH] netcat: make -l exit after handling a request
Sorry for pestering, but have you gotten a chance to take a look at these yet? We're starting to grow dependencies on some of these patches (tests that want to be checked in Soon are being written against a checkout with the patches manually applied) On Fri, Jun 30, 2017 at 12:17 PM, Josh Gao <jm...@google.com> wrote: > Updated the original patch to just jump to cleanup, instead of rearranging > things. > > Also, polished up the proof of concept xgetaddrinfo (this needs a better > name) > patch, and used it to implement -4, -6 (plus another patch to do -u). > > On Thu, Jun 29, 2017 at 6:59 PM, enh <e...@google.com> wrote: > >> ping? various networking folks are looking to add tests that use >> netcat, and i'd rather start them off on toybox netcat rather than BSD >> and then have to move them across to toybox later. (obviously there's >> other missing stuff in toybox, but these patches are the only things >> they actually need right now.) >> >> On Wed, Jun 28, 2017 at 3:47 PM, Josh Gao <jm...@google.com> wrote: >> > On Sun, Jun 25, 2017 at 12:14 PM, Rob Landley <r...@landley.net> wrote: >> >> >> >> 1) switching it to use xconnect() which it predates, and which is hard >> >> because the various users in tree all want slighty different things out >> >> of the getaddrinfo() plumbing and I've made a couple attempts to >> >> unify/genericize it but keep getting pulled alway by $DAYJOB crisis du >> >> jour halfway through and forgetting what design problem details I was >> >> halfway through solving and have to start over again... >> > >> > >> > BTW, I took a quick look at this because we have users that want -4/-6 >> (and >> > IPv6 support in general). `nc -s` makes it so that you can't use >> xconnect >> > because you don't know what to bind to until after you've resolved the >> > target >> > address. Something like xbind_and_connect might work, but there's also >> > things >> > that we might want to do in between socket and bind (e.g. setting >> > SO_REUSEADDR). >> > >> > The thing that everyone really wants is a way to iterate over >> getaddrinfo >> > results; >> > maybe that's what should be exposed? I have a rough proof of concept >> patch >> > attached that implements this and uses it in netcat. >> > >> > (There's also another edge case with -s: what happens if the host you >> pass >> > in >> > resolves to multiple addresses? OpenBSD's netcat seems to just bind the >> > first >> > compatible address it resolves to, so we can maybe just ignore this.) >> > >> > -Josh >> > >> > ___ >> > Toybox mailing list >> > Toybox@lists.landley.net >> > http://lists.landley.net/listinfo.cgi/toybox-landley.net >> > >> >> >> >> -- >> Elliott Hughes - http://who/enh - http://jessies.org/~enh/ >> Android native code/tools questions? Mail me/drop by/add me as a reviewer. >> > > ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] [PATCH] netcat: make -l exit after handling a request
Updated the original patch to just jump to cleanup, instead of rearranging things. Also, polished up the proof of concept xgetaddrinfo (this needs a better name) patch, and used it to implement -4, -6 (plus another patch to do -u). On Thu, Jun 29, 2017 at 6:59 PM, enh <e...@google.com> wrote: > ping? various networking folks are looking to add tests that use > netcat, and i'd rather start them off on toybox netcat rather than BSD > and then have to move them across to toybox later. (obviously there's > other missing stuff in toybox, but these patches are the only things > they actually need right now.) > > On Wed, Jun 28, 2017 at 3:47 PM, Josh Gao <jm...@google.com> wrote: > > On Sun, Jun 25, 2017 at 12:14 PM, Rob Landley <r...@landley.net> wrote: > >> > >> 1) switching it to use xconnect() which it predates, and which is hard > >> because the various users in tree all want slighty different things out > >> of the getaddrinfo() plumbing and I've made a couple attempts to > >> unify/genericize it but keep getting pulled alway by $DAYJOB crisis du > >> jour halfway through and forgetting what design problem details I was > >> halfway through solving and have to start over again... > > > > > > BTW, I took a quick look at this because we have users that want -4/-6 > (and > > IPv6 support in general). `nc -s` makes it so that you can't use xconnect > > because you don't know what to bind to until after you've resolved the > > target > > address. Something like xbind_and_connect might work, but there's also > > things > > that we might want to do in between socket and bind (e.g. setting > > SO_REUSEADDR). > > > > The thing that everyone really wants is a way to iterate over getaddrinfo > > results; > > maybe that's what should be exposed? I have a rough proof of concept > patch > > attached that implements this and uses it in netcat. > > > > (There's also another edge case with -s: what happens if the host you > pass > > in > > resolves to multiple addresses? OpenBSD's netcat seems to just bind the > > first > > compatible address it resolves to, so we can maybe just ignore this.) > > > > -Josh > > > > ___ > > Toybox mailing list > > Toybox@lists.landley.net > > http://lists.landley.net/listinfo.cgi/toybox-landley.net > > > > > > -- > Elliott Hughes - http://who/enh - http://jessies.org/~enh/ > Android native code/tools questions? Mail me/drop by/add me as a reviewer. > From bebee0943874f77bb4a7ff7126ba13738e50a3e3 Mon Sep 17 00:00:00 2001 From: Josh Gao <jm...@google.com> Date: Wed, 28 Jun 2017 15:41:56 -0700 Subject: [PATCH 1/4] Add xgetaddrinfo, use it in netcat. Add a helper function that iterates over getaddrinfo results with a callback, and switch netcat over to it to add support for IPv6. --- lib/lib.h | 2 + lib/net.c | 53 ++- toys/net/netcat.c | 191 ++ 3 files changed, 144 insertions(+), 102 deletions(-) diff --git a/lib/lib.h b/lib/lib.h index 0b93bde..7d12233 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -284,6 +284,8 @@ void tty_sigreset(int i); // net.c int xsocket(int domain, int type, int protocol); void xsetsockopt(int fd, int level, int opt, void *val, socklen_t len); +int xgetaddrinfo(char *host, char *port, int family, int socktype, int protocol, + int flags, int (*cb)(struct addrinfo*, void*), void *cookie); int xconnect(char *host, char *port, int family, int socktype, int protocol, int flags); int xpoll(struct pollfd *fds, int nfds, int timeout); diff --git a/lib/net.c b/lib/net.c index df2551f..b4f5f65 100644 --- a/lib/net.c +++ b/lib/net.c @@ -15,36 +15,55 @@ void xsetsockopt(int fd, int level, int opt, void *val, socklen_t len) if (-1 == setsockopt(fd, level, opt, val, len)) perror_exit("setsockopt"); } -int xconnect(char *host, char *port, int family, int socktype, int protocol, - int flags) +int xgetaddrinfo(char *host, char *port, int family, int socktype, int protocol, + int flags, int (*cb)(struct addrinfo*, void*), void *cookie) { - struct addrinfo info, *ai, *ai2; - int fd; + int rc; + struct addrinfo info, *ai, *ai_head; - memset(, 0, sizeof(struct addrinfo)); + memset(, 0, sizeof(info)); info.ai_family = family; info.ai_socktype = socktype; info.ai_protocol = protocol; info.ai_flags = flags; - fd = getaddrinfo(host, port, , ); - if (fd || !ai) -error_exit("Connect '%s%s%s': %s", host, port ? ":" : "", port ? port : "", - fd ? gai_strerror(fd) : "not found"); - - // Try all the returned a
Re: [Toybox] [PATCH] netcat: make -l exit after handling a request
On Sun, Jun 25, 2017 at 12:14 PM, Rob Landley <r...@landley.net> wrote: > > 1) switching it to use xconnect() which it predates, and which is hard > because the various users in tree all want slighty different things out > of the getaddrinfo() plumbing and I've made a couple attempts to > unify/genericize it but keep getting pulled alway by $DAYJOB crisis du > jour halfway through and forgetting what design problem details I was > halfway through solving and have to start over again... > BTW, I took a quick look at this because we have users that want -4/-6 (and IPv6 support in general). `nc -s` makes it so that you can't use xconnect because you don't know what to bind to until after you've resolved the target address. Something like xbind_and_connect might work, but there's also things that we might want to do in between socket and bind (e.g. setting SO_REUSEADDR). The thing that everyone really wants is a way to iterate over getaddrinfo results; maybe that's what should be exposed? I have a rough proof of concept patch attached that implements this and uses it in netcat. (There's also another edge case with -s: what happens if the host you pass in resolves to multiple addresses? OpenBSD's netcat seems to just bind the first compatible address it resolves to, so we can maybe just ignore this.) -Josh From cd3a377366ed25dcdb821559b39b8319b65eabf0 Mon Sep 17 00:00:00 2001 From: Josh Gao <jm...@google.com> Date: Wed, 28 Jun 2017 15:41:56 -0700 Subject: [PATCH] Add xgetaddrinfo, use it in netcat. Add a helper function that iterates over getaddrinfo results with a callback, and switch netcat over to it to add support for IPv6. --- lib/lib.h | 2 + lib/net.c | 53 +- toys/net/netcat.c | 204 +- 3 files changed, 148 insertions(+), 111 deletions(-) diff --git a/lib/lib.h b/lib/lib.h index 0b93bde..7d12233 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -284,6 +284,8 @@ void tty_sigreset(int i); // net.c int xsocket(int domain, int type, int protocol); void xsetsockopt(int fd, int level, int opt, void *val, socklen_t len); +int xgetaddrinfo(char *host, char *port, int family, int socktype, int protocol, + int flags, int (*cb)(struct addrinfo*, void*), void *cookie); int xconnect(char *host, char *port, int family, int socktype, int protocol, int flags); int xpoll(struct pollfd *fds, int nfds, int timeout); diff --git a/lib/net.c b/lib/net.c index df2551f..b4f5f65 100644 --- a/lib/net.c +++ b/lib/net.c @@ -15,36 +15,55 @@ void xsetsockopt(int fd, int level, int opt, void *val, socklen_t len) if (-1 == setsockopt(fd, level, opt, val, len)) perror_exit("setsockopt"); } -int xconnect(char *host, char *port, int family, int socktype, int protocol, - int flags) +int xgetaddrinfo(char *host, char *port, int family, int socktype, int protocol, + int flags, int (*cb)(struct addrinfo*, void*), void *cookie) { - struct addrinfo info, *ai, *ai2; - int fd; + int rc; + struct addrinfo info, *ai, *ai_head; - memset(, 0, sizeof(struct addrinfo)); + memset(, 0, sizeof(info)); info.ai_family = family; info.ai_socktype = socktype; info.ai_protocol = protocol; info.ai_flags = flags; - fd = getaddrinfo(host, port, , ); - if (fd || !ai) -error_exit("Connect '%s%s%s': %s", host, port ? ":" : "", port ? port : "", - fd ? gai_strerror(fd) : "not found"); - - // Try all the returned addresses. Report errors if last entry can't connect. - for (ai2 = ai; ai; ai = ai->ai_next) { -fd = (ai->ai_next ? socket : xsocket)(ai->ai_family, ai->ai_socktype, - ai->ai_protocol); -if (!connect(fd, ai->ai_addr, ai->ai_addrlen)) break; -else if (!ai->ai_next) perror_exit("connect"); + rc = getaddrinfo(host, port, , ); + if (rc || !ai) { +error_exit("getaddrinfo '%s%s%s': %s", host, port ? ":" : "", port ? port : "", + rc ? gai_strerror(rc) : "not found"); + } + + for (ai_head = ai; ai; ai = ai->ai_next) { +rc = cb(ai, cookie); +if (rc != -1) break; + } + freeaddrinfo(ai_head); + + return rc; +} + +static int _xconnect(struct addrinfo* ai, void *unused) { + int fd; + + fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (fd == -1) { +return -1; + } else if (!connect(fd, ai->ai_addr, ai->ai_addrlen)) { close(fd); +return -1; } - freeaddrinfo(ai2); return fd; } +int xconnect(char *host, char *port, int family, int socktype, int protocol, + int flags) +{ + int rc = xgetaddrinfo(host, port, family, socktype, protocol, flags, _xconnect, 0); + if (rc == -1) perror_exit("connect"); + return rc; +} + int xpoll(struct pollfd *fds, int nfds, int timeout) { int i; diff --git a/toys/n
Re: [Toybox] [PATCH] netcat: make -l exit after handling a request
On Sun, Jun 25, 2017 at 12:14 PM, Rob Landleywrote: > > > terminal1$ echo foo | toybox nc -l -p 1234 > bar > > terminal1$ cat bar > > bar > > Your call there wouldn't work with the "stop after -l" version either, > the -p would have to come before the -l. :P Seems to work for me? > > terminal2$ echo bar | toybox nc localhost 1234 > foo > > terminal2$ cat foo > > foo > > Um... yes? That's what it's supposed to do, and what it's doing without > this patch? > > Your first hunk told it to run an instance of netcat in chat mode (no > command to run, so instead stdin and stdout of netcat get forwarded to > the connection). This will block until the connection is made, although > if you're redirecting the input you can background it if you want to. > > The second hunk then made a connection. The "bar" you wrote to the > second instance got written to the first instance's output, and the > "foo" you wrote to the first instance got forwarded to the second > instance's output. When each instance gets EOF from stdin it calls > shutdown(fd) to let the other instance know, so both instances exit. > > I just built netcat from clean toybox, and it did that. I don't see the > problem? > That's not what I'm seeing. With a freshly compiled tip of tree master (279eb227), the listener doesn't ever exit: # Terminal 1 jmgao@cyclops2:/android/upstream/toybox$ echo foo | ./toybox nc localhost 1234 foo jmgao@cyclops2:/android/upstream/toybox$ echo bar | ./toybox nc localhost 1234 jmgao@cyclops2:/android/upstream/toybox$ echo baz | ./toybox nc localhost 1234 jmgao@cyclops2:/android/upstream/toybox$ # Terminal 2 jmgao@cyclops2:/android/upstream/toybox$ echo foo | ./toybox nc -l -p 1234 foo bar baz ^C jmgao@cyclops2:/android/upstream/toybox$ `toybox nc -l -p 1234 echo foo` works fine because the process execs without forking. Using -l without a command will fall through to pollinate, finish, and then try to listen again. ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] [PATCH] netcat: make -l exit after handling a request
On Fri, Jun 9, 2017 at 1:31 PM, Rob Landley <r...@landley.net> wrote: > On 06/09/2017 01:05 PM, Josh Gao wrote: > > Patch attached. > > What specifically did you fix? (I.E. is this the same "netcat -L > zombies" issue I have on my todo list?) > This makes `nc -l` do what it says it does, and listen for exactly one connection before exiting, instead of handling connections until a ^C. terminal1$ echo foo | toybox nc -l -p 1234 > bar terminal1$ cat bar bar terminal2$ echo bar | toybox nc localhost 1234 > foo terminal2$ cat foo foo (Unrelated: is matching the BSD netcat's command line interface a goal? I keep accidentally doing `toybox nc -l 1234` and getting bitten by it.) I'm -> <- this close to getting a release out, the only issue left after > dmesg is fixing the help text generator, lemme do that, cut a release, > and _then_ dive into this. :) > Sure, thanks :-) -Josh ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
[Toybox] [PATCH] netcat: make -l exit after handling a request
Patch attached. From eceb0b80dcce8a0d20f05b4a47b2e1a69be9b9c9 Mon Sep 17 00:00:00 2001 From: Josh Gao <jm...@google.com> Date: Fri, 9 Jun 2017 10:51:18 -0700 Subject: [PATCH] netcat: make -l exit after handling a request. Bug: http://b/62305466 --- toys/net/netcat.c | 17 - 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/toys/net/netcat.c b/toys/net/netcat.c index 13ba311..795f7b3 100644 --- a/toys/net/netcat.c +++ b/toys/net/netcat.c @@ -126,11 +126,15 @@ void netcat_main(void) // TODO xconnect if (connect(sockfd, (struct sockaddr *)address, sizeof(*address))<0) perror_exit("connect"); + + // We have a connection. Disarm timeout. + set_alarm(0); + in1 = out2 = sockfd; -// Listen for incoming connections - + pollinate(in1, in2, out1, out2, TT.idle, TT.quit_delay); } else { + // Listen for incoming connections socklen_t len = sizeof(*address); if (listen(sockfd, 5)) error_exit("listen"); @@ -143,7 +147,7 @@ void netcat_main(void) if (CFG_TOYBOX_FORK && toys.optc && xfork()) goto cleanup; } - for (;;) { + do { child = 0; len = sizeof(*address); // gcc's insane optimizer can overwrite this in1 = out2 = accept(sockfd, (struct sockaddr *)address, ); @@ -189,15 +193,10 @@ void netcat_main(void) pollinate(in1, in2, out1, out2, TT.idle, TT.quit_delay); close(in1); - } + } while (!(toys.optflags_l)); } } - // We have a connection. Disarm timeout. - set_alarm(0); - - pollinate(in1, in2, out1, out2, TT.idle, TT.quit_delay); - cleanup: if (CFG_TOYBOX_FREE) { close(in1); -- 2.13.0.506.g27d5fe0cd-goog ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] [PATCH] Fix various seq bugs.
On Mon, May 22, 2017 at 11:54 PM, Rob Landleywrote: > > What's the use case for this code? Did they notice a difference from gnu > and say "any difference is a bug", or was somebody actually trying to do > something that broke? > The surprising behavior that I ran into was this: $ seq 100 101 1e+06 1e+06 ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
[Toybox] [PATCH] ps: don't query for terminal size if not a tty
>From an internal bug: $ adb shell # set terminal width to 68 chars sailfish:/ $ ps -A | grep init root 1 0 12344 1556 SyS_epoll+ 0 S init # reduce terminal width to 67 chars sailfish:/ $ ps -A | grep init 1|sailfish:/ $ Patch attached to check isatty(1) before getting the terminal size. From 2f289334ba5d262080a9da1186f0530a5aec1c79 Mon Sep 17 00:00:00 2001 From: Josh Gao <jm...@google.com> Date: Mon, 27 Mar 2017 15:53:03 -0700 Subject: [PATCH] ps: don't query for terminal size if not a tty. `ps -A | cat` shouldn't have different output depending on the size of your terminal window. --- toys/posix/ps.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/toys/posix/ps.c b/toys/posix/ps.c index 0d79b5c..f690671 100644 --- a/toys/posix/ps.c +++ b/toys/posix/ps.c @@ -1149,8 +1149,10 @@ static void shared_main(void) TT.width = 80; TT.height = 25; // If ps can't query terminal size pad to 80 but do -w -if (!terminal_size(, ) && toys.which->name[1] == 's') - toys.optflags |= FLAG_w; +if (toys.which->name[1] == 's') { + if (!isatty(1) || !terminal_size(, )) +toys.optflags |= FLAG_w; +} } // find controlling tty, falling back to /dev/tty if none -- 2.12.2.564.g063fe858b8-goog ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] [PATCH] Make chmod work on . and ..
On Fri, Oct 21, 2016 at 9:22 AM, Rob Landleywrote: > > The problem is without that chmod -R goes nuts. > Whoops, sorry. I probably shouldn't send out patches written immediately before leaving work :-) On Sat, Oct 22, 2016 at 1:43 PM, Rob Landley wrote: > So the design issue this raises is that if you directly do stuff on the > current or previous directories, ala "find . -type f", it should work. > I.E. dirtree_notdotdot() should be if (node->parent) dirtree_notdotdot(); > > There are several places that already test this (like find), and some > that move the notdotdot test later in the function, but it seems like > what should happen is notdotdot() should have the ->parent test > internally. Except: > > mkdir sub > cd sub > touch walrus > rm -rf . > > Complains it can't delete sub (understood, strace on "rmdir ." says the > kernel's returning EINVAL when you try to do that but will happily let > _another_ process do that to you), but does NOT delete walrus (huh? You > can't delete a directory until you've deleted its contents anyway...? > strace says it doesn't even try...?) > > I don't see anything in the rm spec (or man page) about this? > Rob > POSIX says: If either of the files dot or dot-dot are specified as the basename portion of an operand (that is, the final pathname component), rm shall write a diagnostic message to standard error and do nothing more with such operands. ( http://pubs.opengroup.org/onlinepubs/007904975/utilities/rm.html) ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] [PATCH] Make chmod work on . and ..
Trivial patch actually attached... On Thu, Oct 20, 2016 at 8:15 PM, Josh Gao <jm...@google.com> wrote: > Trivial patch attached. > From 232617a915f54e0d8d7fc2ce13e2d75e6ecd958d Mon Sep 17 00:00:00 2001 From: Josh Gao <jm...@google.com> Date: Thu, 20 Oct 2016 20:10:18 -0700 Subject: [PATCH] Make chmod work on . and .. --- toys/posix/chmod.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/toys/posix/chmod.c b/toys/posix/chmod.c index 4292439..288516b 100644 --- a/toys/posix/chmod.c +++ b/toys/posix/chmod.c @@ -43,8 +43,6 @@ static int do_chmod(struct dirtree *try) { mode_t mode; - if (!dirtree_notdotdot(try)) return 0; - mode = string_to_mode(TT.mode, try->st.st_mode); if (toys.optflags & FLAG_v) { char *s = dirtree_path(try, 0); -- 2.8.0.rc3.226.g39d4020 ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] fun with vfork
On Wed, Oct 12, 2016 at 5:49 PM, Rob Landleywrote: > > So... no? I think? Is there a way _I_ can tag this? (I can't do my own > vfork prototype because I can't #undef the one I get out of unistd.h and > that's a fairly generic header. It's sad I can't redo function > prototypes after the fact, but the language never gave me a way to. > Maybe I could do a gratuitous wrapper around it?) > gcc seems to do the equivalent automatically for any function named "vfork": https://github.com/gcc-mirror/gcc/blob/e11be3ea01eaf8acd8cd86d3f9c427621b64e6b4/gcc/calls.c#L533 On Thu, Oct 13, 2016 at 1:03 AM, Rob Landley wrote: > > If I have to gratuitously call setjmp() and ignore its return value > right before calling vfork() to beat reliable behavior out of gcc, I can > do that. I can also use global variables instead of local variables, or > make a structure of local variables so gcc can't gratuitously reorganize > them and trim the stack, or have my one allowed phone > function call be to a function I define that contains "everything the > child does" to preserve the stack context. > > Personally, I'd rather the compiler didn't fight me when I'm trying to > do something obvious, but I have LOTS of ways to fight back. :) It doesn't seem like gcc differentiates between vfork, setjmp, etc. so it's presumably providing some behavior that satisfies the constraints of all of them (or there's a bug). The specification for longjmp says that only non-volatile local variables that get modified have unspecified values, so you could maybe try sprinkling volatile on things to see if it makes your problem go away? ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] fun with vfork
Do you have vfork tagged with __attribute__((returns_twice))? AFAIK, that's the incantation to get gcc to do the right thing for setjmpy functions. On Oct 11, 2016 4:23 AM, "Rob Landley"wrote: > While doing the rest of nommu support in netcat -L, I had some variant of: > > function() > { > int child, blah = 3; > > for (;;) { > crunch(blah); > child = vfork(); > if (child<1) break; > } > thingy(); > > execlp(stuff); > } > > And gcc's optimizer went "blah isn't used anymore after the for loop, > I'll trim the stack frame down so the return address in the call to > thingy() in the child overwrites it, and then when vfork returns it's > corrupted in the parent and the next call to crunch() goes bye-bye". > Because gcc's optimizer does not understand vfork()'s impact on > "liveness analysis". (You can think of vfork() as a setjmp that will > fork() when it hits the next exec or exit, and then the parent process > longjmp()s back to the stack until the child. But gcc's optimizer doesn't.) > > The fix is to add an unnecessary use of blah to the end of the function > to let it know it's still %*#(%&& used, but then I need a GREAT BIG > COMMENT to explain why so it isn't removed in future cleanup passes. And > every other variable potentially has that same problem. > > As usual, I want to punch gcc's optimizer in the face and go "DO WHAT I > TOLD YOU TO DO, DON'T MAKE STUFF UP!" but it never listens. (Do I have > to start building everything with -O0? What optimization level gives me > dead code elimination and nothing else?) > > Rob > > P.S. I'm always amused by the go/rust/swift developers who haven't hit > their language with anything like the range of use cases you get in C, > confidently stating that they have yet to see such strange corner cases > in _their_ language yet. Uh-huh. There's a reason for that and it's > probably not the one you think. > ___ > Toybox mailing list > Toybox@lists.landley.net > http://lists.landley.net/listinfo.cgi/toybox-landley.net > ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
Re: [Toybox] Kernighan's awk repo
On Jul 22, 2016 12:46 AM, "Rob Landley"wrote: > > 's not a bug if you never use the result. Not unless you enable > something that traps on an integer overflow or similar. FWIW, the standard explicitly says it's undefined behavior, and clang and gcc seem to be in a competition to find new and inventive ways to optimize seemingly benign UB into broken programs. Just because it works now doesn't mean it'll stay that way. ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
[Toybox] [PATCH] Fix "tail -f single_file".
TT.file_no was being incorrectly calculated as 0 when tail -f was passed a single argument, so tail -f with one argument wouldn't actually do the '-f' part. Patch attached. From 3feb4ae50b5135e7c9c8870968f87e318c615ba2 Mon Sep 17 00:00:00 2001 From: Josh Gao <jm...@google.com> Date: Wed, 16 Mar 2016 15:41:13 -0700 Subject: [PATCH] Fix "tail -f single_file". TT.file_no was being incorrectly calculated as 0 when tail -f was passed a single argument. --- toys/posix/tail.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toys/posix/tail.c b/toys/posix/tail.c index d1c6250..bf25a14 100644 --- a/toys/posix/tail.c +++ b/toys/posix/tail.c @@ -136,7 +136,7 @@ static void do_tail(int fd, char *name) int linepop = 1; if (toys.optflags & FLAG_f) { -int f = TT.file_no*2; +int f = (TT.file_no++)*2; char *s = name; if (!fd) sprintf(s = toybuf, "/proc/self/fd/%d", fd); @@ -146,7 +146,7 @@ static void do_tail(int fd, char *name) } if (toys.optc > 1) { -if (TT.file_no++) xputc('\n'); +if (TT.file_no) xputc('\n'); xprintf("==> %s <==\n", name); } -- 2.7.0.rc3.207.g0ac5344 ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
[Toybox] [PATCH] Fix segfault in `find . -iname`
Two patches attached (are github pull requests more convenient for you?) From ef19fb43d16432cfce54ee7fe940f3fa0a87ae8a Mon Sep 17 00:00:00 2001 From: Josh Gao <jm...@google.com> Date: Thu, 4 Feb 2016 10:43:20 -0800 Subject: [PATCH 1/2] Fix null dereference prior to check. --- toys/posix/find.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/toys/posix/find.c b/toys/posix/find.c index febe688..ac5eaac 100644 --- a/toys/posix/find.c +++ b/toys/posix/find.c @@ -315,7 +315,11 @@ static int do_find(struct dirtree *new) || !strcmp(s, "path") || !strcmp(s, "ipath")) { int i = (*s == 'i'); -char *arg = ss[1], *path = 0, *name = new->name; +char *arg = ss[1], *path = 0, *name = 0; + +if (new) { + name = new->name; +} // Handle path expansion and case flattening if (new && s[i] == 'p') name = path = dirtree_path(new, 0); -- 2.7.0.rc3.207.g0ac5344 From 59a7187d0eb2db6fd5cb68854d3195239cb0daad Mon Sep 17 00:00:00 2001 From: Josh Gao <jm...@google.com> Date: Thu, 4 Feb 2016 10:49:52 -0800 Subject: [PATCH 2/2] Fix segfault when `find -iname` gets no argument. --- tests/find.test | 16 toys/posix/find.c | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/find.test b/tests/find.test index 4e987b6..710684e 100755 --- a/tests/find.test +++ b/tests/find.test @@ -74,4 +74,20 @@ testing "find unterminated -exec {}" \ testing "find -exec {} +" \ "find dir -type f -exec ls {} +" "dir/file\n" "" "" +# `find . -iname` was segfaulting +testing "find -name file" \ + "find dir -name file" "dir/file\n" "" "" +testing "find -name FILE" \ + "find dir -name FILE" "" "" "" + +testing "find -iname file" \ + "find dir -iname FILE" "dir/file\n" "" "" +testing "find -iname FILE" \ + "find dir -iname FILE" "dir/file\n" "" "" + + +testing "find -name (no arguments)" \ + "find dir -name 2>&1" "find: '-name' needs 1 arg\n" "" "" +testing "find -iname (no arguments)" \ + "find dir -iname 2>&1" "find: '-iname' needs 1 arg\n" "" "" rm -rf dir diff --git a/toys/posix/find.c b/toys/posix/find.c index ac5eaac..d3ee7f5 100644 --- a/toys/posix/find.c +++ b/toys/posix/find.c @@ -325,7 +325,8 @@ static int do_find(struct dirtree *new) if (new && s[i] == 'p') name = path = dirtree_path(new, 0); if (i) { if (check || !new) { -name = strlower(new ? name : arg); +char *temp = new ? name : arg; +name = temp ? strlower(temp) : 0; if (!new) { dlist_add(, name); free(path); -- 2.7.0.rc3.207.g0ac5344 ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
[Toybox] [PATCH] Implement tail -f.
Patch attached because I don't trust gmail to not mangle it. From 394e1330bbeba6aed1f7897ea981610d5a925187 Mon Sep 17 00:00:00 2001 From: Josh Gao <jm...@google.com> Date: Fri, 4 Dec 2015 13:30:02 -0800 Subject: [PATCH] Implement tail -f. --- toys/posix/tail.c | 74 --- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/toys/posix/tail.c b/toys/posix/tail.c index 80556e2..1df549d 100644 --- a/toys/posix/tail.c +++ b/toys/posix/tail.c @@ -17,7 +17,7 @@ config TAIL -n output the last NUMBER lines (default 10), +X counts from start. -c output the last NUMBER bytes, +NUMBER counts from start -#-f follow FILE(s), waiting for more data to be appended [TODO] +-f follow FILE(s), waiting for more data to be appended config TAIL_SEEK bool "tail seek support" @@ -30,11 +30,20 @@ config TAIL_SEEK #define FOR_tail #include "toys.h" +#include + +struct file_info { + int fd; + int wd; + const char* path; +}; + GLOBALS( long lines; long bytes; int file_no; + struct file_info *files; ) struct line_list { @@ -135,10 +144,15 @@ static void do_tail(int fd, char *name) int linepop = 1; if (toys.optc > 1) { -if (TT.file_no++) xputc('\n'); +if (TT.file_no > 0) xputc('\n'); xprintf("==> %s <==\n", name); } + // -f support: cache name/descriptor + TT.files[TT.file_no].fd = dup(fd); + TT.files[TT.file_no].path = strdup(name); + ++TT.file_no; + // Are we measuring from the end of the file? if (bytes<0 || lines<0) { @@ -207,8 +221,6 @@ static void do_tail(int fd, char *name) } if (offset<len) xwrite(1, toybuf+offset, len-offset); } - - // -f support: cache name/descriptor } void tail_main(void) @@ -228,7 +240,61 @@ void tail_main(void) TT.lines = -10; } + TT.files = xmalloc(toys.optc * sizeof(struct file_info)); loopfiles(args, do_tail); // do -f stuff + if (toys.optflags & FLAG_f) { +int infd, last_wd, i; + +infd = inotify_init(); +if (infd < 0) { + perror_exit("failed to create inotify fd"); +} + +for (i = 0; i < TT.file_no; ++i) { + #define STR(x) #x + char path[sizeof("/proc/self/fd/" STR(INT_MIN))]; + + snprintf(path, sizeof(path), "/proc/self/fd/%d", TT.files[i].fd); + + TT.files[i].wd = inotify_add_watch(infd, path, IN_MODIFY); + if (TT.files[i].wd < 0) { +perror_msg("failed to add inotify watch for %s", TT.files[i].path); +continue; + } +} + +last_wd = TT.files[TT.file_no - 1].wd; + +while (1) { + struct inotify_event ev; + int len; + + len = read(infd, , sizeof(ev)); + if (len < 0) { +perror_exit("inotify read failed"); + } + + for (i = 0; i < TT.file_no; ++i) { +if (ev.wd != TT.files[i].wd) { + continue; +} + +// Read until we hit the end. +while (1) { + len = read(TT.files[i].fd, toybuf, sizeof(toybuf)); + if (len <= 0) break; + + if (last_wd != TT.files[i].wd) { +last_wd = TT.files[i].wd; +xprintf("\n==> %s <==\n", TT.files[i].path); + } + + xwrite(1, toybuf, len); +} +break; + } +} + } } -- 2.6.0.rc2.230.g3dd15c0 ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net
[Toybox] [PATCH] tail: use off_t instead of ssize_t for file offset.
From 40fcc693c339ab9cafba7cf6f68cdb8b430401cf Mon Sep 17 00:00:00 2001 From: Josh Gao <jm...@google.com> Date: Fri, 4 Dec 2015 15:12:15 -0800 Subject: [PATCH] tail: use off_t instead of ssize_t for file offset. --- toys/posix/tail.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toys/posix/tail.c b/toys/posix/tail.c index 80556e2..910b88f 100644 --- a/toys/posix/tail.c +++ b/toys/posix/tail.c @@ -74,7 +74,7 @@ static int try_lseek(int fd, long bytes, long lines) { struct line_list *list = 0, *temp; int flag = 0, chunk = sizeof(toybuf); - ssize_t pos = lseek(fd, 0, SEEK_END); + off_t pos = lseek(fd, 0, SEEK_END); // If lseek() doesn't work on this stream, return now. if (pos<0) return 0; -- 2.6.0.rc2.230.g3dd15c0 ___ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net