select function may upate timeout parameter in linux.why it is 'may update'?
<p>My operating system is Centos 6.4.</p>

<p>For select the linux programmer's manual says: "select may update the timeout parameter to indicate how much time was left...."</p>

<p>I wonder why it is 'may' rather than 'must'? Is there a system version or a kernel version?</p>

<p>I make a test.
test_code01.cpp</p>

<pre><code>#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;errno.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;resolv.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;netinet/in.h&gt;
#include &lt;arpa/inet.h&gt;
#include &lt;unistd.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;sys/time.h&gt;
#include &lt;pthread.h&gt;

#define BUFSIZE 1024

struct timeval g_timeout;

int main(int argc, char* argv[])
{
    int sock_clientfd, ret_recvsize, i;
    struct sockaddr_in dest, mine;
    char buffer[BUFSIZE + 1];

    // create socket fd
    if ((sock_clientfd = socket(AF_INET, SOCK_STREAM, 0)) &lt; 0)
    {
        perror("Socket");
        exit(EXIT_FAILURE);
    }

    // init server address that client will connetct to.
    bzero(&amp;dest, sizeof(dest));
    dest.sin_family = AF_INET;
    dest.sin_port = htons(9567);
    if(argc != 2)
    {
        printf("Usage: %s &lt;dest ip&gt;\n", argv[0]);
        printf("Usage: %s 127.0.0.1\n", argv[0]);
        return -1;
    }

    printf("-----\n");

    if (inet_aton(argv[1], (struct in_addr *) &amp;dest.sin_addr.s_addr) == 0)
    {
        perror(argv[1]);
        exit(1);
    }

    // connect to server
    printf("will connect!\n");
    if (connect(sock_clientfd, (struct sockaddr *) &amp;dest, sizeof(dest)) != 0)
    {
        perror("Connect ");
        exit(EXIT_FAILURE);
    }

    int ret_select = 0;
    fd_set readfds;
    FD_SET(sock_clientfd, &amp;readfds);

    g_timeout.tv_sec = 3;
    g_timeout.tv_usec = 0;

    while(1)
    {
        ret_select = select(sock_clientfd + 1, &amp;readfds, NULL, NULL, &amp;g_timeout);

        // Becasue select can update timeout, we need to set value for timeout.
        // g_timeout.tv_sec = 3;
        // g_timeout.tv_usec = 0;

        // Recover sock_clienfd state
        FD_SET(sock_clientfd, &amp;readfds);

        if(ret_select == 0)
        {
            printf("select wait timeout.\n");
            continue;
        }

        bzero(buffer, BUFSIZE + 1);
        ret_recvsize = recv(sock_clientfd, buffer, BUFSIZE, 0);
        if(ret_recvsize &gt; 0)
        {
            printf("get %d message:%s", strlen(buffer), buffer);
            ret_recvsize=0;
        }
        else
        {
            printf("no data from server\n");
        }
    }

    // close sock_clientfd
    close(sock_clientfd);

    return 0;
}
</code></pre>

<p>I execute this test_code01.cpp, and the result select wait for 3 seconds for only first times.In my opinion, the select modify timeout.So I modify code follow:</p>

<pre><code>#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;errno.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;resolv.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;netinet/in.h&gt;
#include &lt;arpa/inet.h&gt;
#include &lt;unistd.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;sys/time.h&gt;
#include &lt;pthread.h&gt;

#define BUFSIZE 1024

// in order to facilitate the ovservation data
// the timeout is set to global varible
struct timeval g_timeout;

void* thredproc_looktimeout(void*)
{
    while(1)
    {
        printf("left time: %ds %dms\n", g_timeout.tv_sec, g_timeout.tv_usec);
    }
}

int main(int argc, char* argv[])
{
    int sock_clientfd, ret_recvsize, i;
    struct sockaddr_in dest, mine;
    char buffer[BUFSIZE + 1];

    // create socket fd
    if ((sock_clientfd = socket(AF_INET, SOCK_STREAM, 0)) &lt; 0)
    {
        perror("Socket");
        exit(EXIT_FAILURE);
    }

    // init server address that client will connetct to.
    bzero(&amp;dest, sizeof(dest));
    dest.sin_family = AF_INET;
    dest.sin_port = htons(9567);
    if(argc != 2)
    {
        printf("Usage: %s &lt;dest ip&gt;\n", argv[0]);
        printf("Usage: %s 127.0.0.1\n", argv[0]);
        return -1;
    }

    printf("-----\n");

    if (inet_aton(argv[1], (struct in_addr *) &amp;dest.sin_addr.s_addr) == 0)
    {
        perror(argv[1]);
        exit(1);
    }

    // connect to server
    printf("will connect!\n");
    if (connect(sock_clientfd, (struct sockaddr *) &amp;dest, sizeof(dest)) != 0)
    {
        perror("Connect ");
        exit(EXIT_FAILURE);
    }

    int ret_select = 0;
    fd_set readfds;
    FD_SET(sock_clientfd, &amp;readfds);
    printf("fdset add fd start+++\n");
    for(int i = 0; i &lt; 2000; i++)
    {
        FD_SET(1025+i, &amp;readfds);
    }
    printf("%d--%s\n", errno, strerror(errno));
    printf("fdset add 2000 fd finish...\n");

    g_timeout.tv_sec = 3;
    g_timeout.tv_usec = 0;


    /**
     *  look timeout left time by create thread
     **/
    pthread_t tid;
    int ret_pthreadcreate = pthread_create(&amp;tid, NULL, thredproc_looktimeout, NULL);
    printf("pthread_create return value is %d\n", ret_pthreadcreate);

    while(1)
    {
        ret_select = select(sock_clientfd + 1, &amp;readfds, NULL, NULL, &amp;g_timeout);

        // Becasue select can update timeout, we need to set value for timeout.
        g_timeout.tv_sec = 3;
        g_timeout.tv_usec = 0;

        // Recover sock_clienfd state
        FD_SET(sock_clientfd, &amp;readfds);

        if(ret_select == 0)
        {
            printf("select wait timeout.\n");
            continue;
        }

        bzero(buffer, BUFSIZE + 1);
        ret_recvsize = recv(sock_clientfd, buffer, BUFSIZE, 0);
        if(ret_recvsize &gt; 0)
        {
            printf("get %d message:%s", strlen(buffer), buffer);
            ret_recvsize=0;
        }
        else
        {
            printf("no data from server\n");
        }
    }

    // close sock_clientfd
    close(sock_clientfd);

    return 0;
}
</code></pre>

<p>I think we should see a change in timeout in thredproc_looktimeout.But no change.I don't know why?</p>