What if we deliberately use ‘struct timeval’ like this incorrect way to set timeout of receiving to 3 seconds:

struct timeval tv = {1, 2000000};
setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv));

the ‘setsockopt’ will return fail (-1).

Let’s look up the linux kernel code for systemcall sys_setsockopt():

SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,                     
        char __user *, optval, int, optlen)                                        
{   
    int err, fput_needed;                                                          
    struct socket *sock;                                                           
    
    if (optlen < 0)                                                                
        return -EINVAL;                                                            
    
    sock = sockfd_lookup_light(fd, &err, &fput_needed);                            
    if (sock != NULL) {                                                            
        err = security_socket_setsockopt(sock, level, optname);                    
        if (err)
            goto out_put;
                                                                                   
        if (level == SOL_SOCKET)                                                   
            err =
                sock_setsockopt(sock, level, optname, optval,                      
                        optlen);
        else
            err =                                                                  
                sock->ops->setsockopt(sock, level, optname, optval,                
                          optlen);                                                 
out_put:
        fput_light(sock->file, fput_needed);                                       
    }
    return err;
}       

sock_setsockopt() will invoke sock_set_timeout() and sock_set_timeout() looks like:

static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
{
    struct timeval tv;

    if (optlen < sizeof(tv))
        return -EINVAL;
    if (copy_from_user(&tv, optval, sizeof(tv)))
        return -EFAULT;
    if (tv.tv_usec < 0 || tv.tv_usec >= USEC_PER_SEC)
        return -EDOM;
......

That’s it. If ‘tv.tv_usec’ is greater than USEC_PER_SEC (which equals 1000000), it will return -EDOM and setsockopt() will fail.