Re: [Toybox] [PATCH] tr: fix pathological flushing.

2020-12-05 Thread Josh Gao via Toybox
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.

2020-05-04 Thread Josh Gao via Toybox
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.

2019-08-08 Thread Josh Gao via Toybox
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.

2019-04-08 Thread Josh Gao via Toybox
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?

2019-03-08 Thread Josh Gao via Toybox
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

2019-01-25 Thread Josh Gao via Toybox
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

2019-01-24 Thread Josh Gao via Toybox
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`.

2019-01-02 Thread Josh Gao via Toybox

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

2018-12-10 Thread Josh Gao via Toybox
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.

2018-10-30 Thread Josh Gao
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)

2017-12-08 Thread Josh Gao
On Fri, Dec 8, 2017 at 6:12 PM, Rob Landley  wrote:
>
> 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

2017-07-18 Thread Josh Gao
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

2017-06-30 Thread Josh Gao
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

2017-06-28 Thread Josh Gao
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

2017-06-26 Thread Josh Gao
On Sun, Jun 25, 2017 at 12:14 PM, Rob Landley  wrote:
>
> > 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

2017-06-09 Thread Josh Gao
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

2017-06-09 Thread Josh Gao
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.

2017-05-23 Thread Josh Gao
On Mon, May 22, 2017 at 11:54 PM, Rob Landley  wrote:
>
> 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

2017-03-27 Thread Josh Gao
>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 ..

2016-10-25 Thread Josh Gao
On Fri, Oct 21, 2016 at 9:22 AM, Rob Landley  wrote:
>
> 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 ..

2016-10-20 Thread Josh Gao
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

2016-10-13 Thread Josh Gao
On Wed, Oct 12, 2016 at 5:49 PM, Rob Landley  wrote:
>
> 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

2016-10-11 Thread Josh Gao
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

2016-07-22 Thread Josh Gao
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".

2016-03-19 Thread Josh Gao
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`

2016-02-04 Thread Josh Gao
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.

2015-12-05 Thread Josh Gao
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.

2015-12-05 Thread Josh Gao

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