0

I'm trying to use loginhook to download large amounts of data and I've been having problems which I've nailed down to nc exiting prematurely for no apparent reason. This is a simplified test script:

#!/bin/bash exec > /tmp/lhook.out.txt 2> /tmp/lhook.err.txt nc -v server 4444 > /tmp/nc-test echo "Exit value: $?"

On the server, when I run a simple nc listener like echo "Hello world. | nc -l 4444, the transfer works correctly. But when I want to transfer a larger file, like nc -l 4444 < /path/to/some/large.file, the client transfers only a small part (sometimes 2kiB, sometimes ~250 kiB). The exit value reported is 0.

Oh, and of course - the same script executed in a Terminal.app inside a user session works fine.

Can someone help with debugging, explain what is going on, or provide a solution?

EDIT: I've had dtruss snoop on netcat's syscalls, and this is what I got:

  157/0x4c6:  write(0x1, "j,\350\037\376\377\377\203\304$f\211F\016\350&f\004\0", 0x400)                 = 1024 0
  157/0x4c6:  select(0x5, 0x7FFF53A87B40, 0x0, 0x0, 0x0)                 = 1 0
  157/0x4c6:  read(0x4, "\001u\374)u\f\215\f6\203\304\020\003\331\001\b\353\035\017\267\003\213\027P\213\317\377R\004\271\377\377\0", 0x400)    
         = 1024 0
  157/0x4c6:  write(0x1, "\001u\374)u\f\215\f6\203\304\020\003\331\001\b\353\035\017\267\003\213\027P\213\317\377R\004\271\377\377\0", 0x400)   
         = 1024 0
  157/0x4c6:  select(0x5, 0x7FFF53A87B40, 0x0, 0x0, 0x0)                 = 1 0
  157/0x4c6:  read(0x4, "\0", 0x400)             = 0 0
  157/0x4c6:  shutdown(0x4, 0x0, 0x0)            = -1 Err#57
  157/0x4c6:  close(0x4)                 = 0 0
  157/0x4c6:  close(0x3)                 = 0 0
  157/0x4c6:  close(0x3)                 = -1 Err#9

I'm guessing that for some reason, the kernel is giving nc EOF instead of waiting for more data.

1 Answer 1

0

What an embarrassing oversight... :-(

nc quits upon reading EOF from stdin. The client which receives the data runs the LoginHook script in a non-interactive shell, which directs nc's stdin descriptor probably to /dev/null. As soon as it reads EOF from it, it quits.

The fix is trivial: supply -d switch to the receiving side. This prevents either version of netcat (BSD or Linux) from reading stdin, and the transfrer completes without issue.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .