introduce safe_poll (fixes a problem in top)

function                                             old     new   delta
safe_poll                                              -      77     +77
svlogd_main                                         1470    1466      -4
zcip_main                                           1530    1524      -6
forkexec                                            1345    1338      -7
decode_format_string                                 795     788      -7
collect_blk                                          474     467      -7
buffer_pread                                         540     532      -8
tftp                                                1182    1172     -10
microcom_main                                        763     749     -14
arpping                                              441     424     -17
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/9 up/down: 77/-80)             Total: -3 bytes
   text    data     bss     dec     hex filename
 770162    1034   10404  781600   bed20 busybox_old
 770158    1034   10404  781596   bed1c busybox_unstripped

diff --git a/libbb/safe_poll.c b/libbb/safe_poll.c
new file mode 100644
index 0000000..d2b773c
--- /dev/null
+++ b/libbb/safe_poll.c
@@ -0,0 +1,34 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Utility routines.
+ *
+ * Copyright (C) 2007 by Denys Vlasenko <vda.linux@googlemail.com>
+ *
+ * Licensed under GPLv2, see file LICENSE in this tarball for details.
+ */
+
+#include "libbb.h"
+
+/* Wrapper which restarts poll on EINTR or ENOMEM.
+ * On other errors does perror("poll") and returns.
+ * Warning! May take longer than timeout_ms to return! */
+int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout)
+{
+	while (1) {
+		int n = poll(ufds, nfds, timeout);
+		if (n >= 0)
+			return n;
+		/* Make sure we inch towards completion */
+		if (timeout > 0)
+			timeout--;
+		/* E.g. strace causes poll to return this */
+		if (errno == EINTR)
+			continue;
+		/* Kernel is very low on memory. Retry. */
+		/* I doubt many callers would handle this correctly! */
+		if (errno == ENOMEM)
+			continue;
+		bb_perror_msg("poll");
+		return n;
+	}
+}