diff options
Diffstat (limited to 'vio')
-rw-r--r-- | vio/vio.c | 16 | ||||
-rw-r--r-- | vio/viosocket.c | 11 |
2 files changed, 21 insertions, 6 deletions
diff --git a/vio/vio.c b/vio/vio.c index e444c634c96..ff93cff959f 100644 --- a/vio/vio.c +++ b/vio/vio.c @@ -149,10 +149,18 @@ Vio *vio_new(my_socket sd, enum enum_vio_type type, uint flags) vio->sd); #if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) #if !defined(NO_FCNTL_NONBLOCK) -#if defined(__FreeBSD__) - fcntl(sd, F_SETFL, vio->fcntl_mode); /* Yahoo! FreeBSD patch */ -#endif - vio->fcntl_mode = fcntl(sd, F_GETFL); + /* + We call fcntl() to set the flags and then immediately read them back + to make sure that we and the system are in agreement on the state of + things. + + An example of why we need to do this is FreeBSD (and apparently some + other BSD-derived systems, like Mac OS X), where the system sometimes + reports that the socket is set for non-blocking when it really will + block. + */ + fcntl(sd, F_SETFL, 0); + vio->fcntl_mode= fcntl(sd, F_GETFL); #elif defined(HAVE_SYS_IOCTL_H) /* hpux */ /* Non blocking sockets doesn't work good on HPUX 11.0 */ (void) ioctl(sd,FIOSNBIO,0); diff --git a/vio/viosocket.c b/vio/viosocket.c index e0ca18539ce..5e0ed20b039 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -138,14 +138,21 @@ int vio_blocking(Vio * vio __attribute__((unused)), my_bool set_blocking_mode, else vio->fcntl_mode |= O_NONBLOCK; /* set bit */ if (old_fcntl != vio->fcntl_mode) - r = fcntl(vio->sd, F_SETFL, vio->fcntl_mode); + { + r= fcntl(vio->sd, F_SETFL, vio->fcntl_mode); + if (r == -1) + { + DBUG_PRINT("info", ("fcntl failed, errno %d", errno)); + vio->fcntl_mode= old_fcntl; + } + } } #else r= set_blocking_mode ? 0 : 1; #endif /* !defined(NO_FCNTL_NONBLOCK) */ #else /* !defined(__WIN__) && !defined(__EMX__) */ #ifndef __EMX__ - if (vio->type != VIO_TYPE_NAMEDPIPE) + if (vio->type != VIO_TYPE_NAMEDPIPE && vio->type != VIO_TYPE_SHARED_MEMORY) #endif { ulong arg; |