fun fact about TCP

There’s one less-than-expected thing about TCP: even if you provide a small buffer to recv() and the other side sends exactly the same amount of data in the send() call, there’s no guarantee that the data is received in one call.

Take for example Python:

# sock is a socket.socket(), already connected
data = socket.recv(4)
length = struct.unpack('=l', data)[0]  # this might fail!

There are two ways to mitigate it:

  • really portable way: receive in a loop, until all data are received – but beware of recv() returning b'' – this means there’s an error in the communication
  • Linux/Unix way: use MSG_WAITALL flag to force recv() to block until whole buffer is filled

split string in python

Python splits string via str.split() and str.rsplit() as well, the latter of which starts splitting from the end of the string.
This can be useful when using the second parameter, maxsplit.

For example:

>>> "string with multiple spaces".split(" ", maxsplit=1)
['string', 'with multiple spaces']

This parameter can be used e.g. to split command and arguments apart.

print strace summary

To summarise syscalls by time or count, use strace -c. To include child processed, add -f switch. For example:

λ strace -cf git status
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.000008           0       247        24 lstat
  0.00    0.000000           0        48           read
  0.00    0.000000           0         3           write
                     ... list goes on ...

shorter for-loops in zsh

When running a for-loop in zsh, you can skip do-done part, leaving only command, for example:

% for day in Mon Tue Wed Thu; date -d "next $day"
Mon Apr 25 00:00:00 CEST 2016
Tue Apr 26 00:00:00 CEST 2016
Wed Apr 27 00:00:00 CEST 2016
Thu Apr 28 00:00:00 CEST 2016

Caveat: this doesn’t work on multiple commands in one loop — for day in Mon Tue Wed Thu; echo $day; date -d "next $day" won’t work as expected