- alarm(1);
- len = ber(message, varbindlist, num, type);
- if (sendto(sockfd, message, len, 0, (struct sockaddr *) &server, SIZE)
- == -1) {
- alarm(0);
- return 0;
- }
- if ((len = recv(sockfd, message, 1024, 0)) == -1) {
- alarm(0);
- return 0;
+ FD_ZERO(&rds);
+ FD_SET(sockfd, &rds);
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ if (select(sockfd + 1, &rds, NULL, NULL, &timeout) == -1)
+ return 0;
+
+ if (FD_ISSET(sockfd, &rds)) {
+ if ((len = recv(sockfd, buf, sizeof buf, 0)) <= 0)
+ return 0;
+ else
+ break;
+ }
+
+ /* timeout => next try, as long as no key has been pressed */
+
+ /*
+ * Allow for quick 'last resort' escape using q/Q. Note:
+ * we may not use one select() for checking both fd 0 and sockfd, since
+ * something may appear on sockfd later than key has been pressed =>
+ * give gratuitous 1sec delay for response arrival to sockfd, and THEN
+ * just poll for anything on fd 0.
+ */
+ if (snmp_quit_by_keypress && type == GET) {
+ FD_ZERO(&rds);
+ FD_SET(0, &rds);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ if (select(1, &rds, NULL, NULL, &timeout) == -1)
+ return 0;
+
+ if (FD_ISSET(0, &rds))
+ return 0;
+ }