Last active
March 5, 2024 21:52
-
-
Save overhacked/0b041af7994c06f9b6837876083deb72 to your computer and use it in GitHub Desktop.
Little C program to find the maximum value of select's timeout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <fcntl.h> | |
#include <limits.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/fcntl.h> | |
#include <sys/select.h> | |
/* min and max integer values. T is a signed or unsigned integer type. */ | |
/* Returns 1 if T is signed, else 0. */ | |
#define INTTYPE_SIGNED(T) ((T)-1 < (T)0) | |
/* | |
* Returns (T)(maximum value of a T). | |
* | |
* Pains are taken (perhaps unnecessarily) to avoid integer overflow | |
* with signed types. | |
*/ | |
#define INTTYPE_MAX(T) \ | |
(((T)1 << (CHAR_BIT*sizeof(T)-INTTYPE_SIGNED(T)-1)) - 1 + \ | |
((T)1 << (CHAR_BIT*sizeof(T)-INTTYPE_SIGNED(T)-1))) | |
/* | |
* Returns (T)(minimum value of a T). | |
* Pains are taken (perhaps unnecessarily) to avoid integer overflow | |
* with signed types. | |
* assert: twos complement architecture | |
*/ | |
#define INTTYPE_MIN(T) ((T)(-INTTYPE_MAX(T)-1)) | |
/* Returns 1 if V has signed type, else 0. */ | |
#define INT_VALUE_SIGNED(V) ((V)-(V)-1 < 0) | |
/* | |
* Returns maximum value for V's type. | |
* | |
* Pains are taken (perhaps unnecessarily) to avoid integer overflow | |
* with signed types. | |
*/ | |
#define INT_VALUE_MAX(V) \ | |
(((V)-(V)+1 << (CHAR_BIT*sizeof(V)-INT_VALUE_SIGNED(V)-1)) - 1 + \ | |
((V)-(V)+1 << (CHAR_BIT*sizeof(V)-INT_VALUE_SIGNED(V)-1))) | |
/* | |
* Returns minimum value for V's type. | |
* Pains are taken (perhaps unnecessarily) to avoid integer overflow | |
* with signed types. | |
* assert: twos complement architecture | |
*/ | |
#define INT_VALUE_MIN(V) (-INT_VALUE_MAX(V)-1)int: INT_MAX, unsigned int: UINT_MAX) | |
int | |
main(void) | |
{ | |
int retval, devzero_fd; | |
fd_set rfds; | |
struct timeval tv; | |
__darwin_time_t search_lower, search_upper; | |
/* Read from /dev/zero, so there is always input */ | |
devzero_fd = open("/dev/zero", O_RDONLY); | |
/* Decrement from the maximum value of tv.tv_sec to find the | |
* maximum value accepted by select(); start the lower bounds | |
* of the search at the max 32-bit integer, because it is a | |
* known-working value. */ | |
// search_lower = INT_VALUE_MAX(tv.tv_sec) >> 31; | |
search_lower = 0; | |
search_upper = INT_VALUE_MAX(tv.tv_sec); | |
tv.tv_usec = 0; | |
while (search_lower <= search_upper) { | |
tv.tv_sec = search_lower + ((search_upper - search_lower) / 2); | |
printf("select(..., %ld)\n", tv.tv_sec); | |
FD_ZERO(&rfds); | |
FD_SET(devzero_fd, &rfds); | |
retval = select(devzero_fd + 1, &rfds, NULL, NULL, &tv); | |
if (retval > 0) | |
search_lower = tv.tv_sec + 1; | |
else if (retval < 0) { | |
search_upper = tv.tv_sec - 1; | |
} | |
} | |
if (retval == -1) { | |
tv.tv_sec -= 1; | |
if (!select(1, &rfds, NULL, NULL, &tv)) | |
perror("select()"); | |
} | |
printf("\nMaximum value for tv.tv_sec=%ld\n", tv.tv_sec); | |
exit(EXIT_SUCCESS); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment