PHP 4.0 Bug #5823: PHP assumes MySQL unix socket is always available
| From: | dolecek at ibis dot cz | Date: | Thu, 27 Jul 2000 19:04:12 +0000 |
| Subject: | PHP 4.0 Bug #5823: PHP assumes MySQL unix socket is always available | ||
| Groups: | php.dev | ||
| Request: | Send a blank email to php-dev+get-26566@lists.php.net to get a copy of this message | ||
From: dolecek@ibis.cz
Operating system: NetBSD-1.5_ALPHA
PHP version: 4.0.1pl2
PHP Bug Type: MySQL related
Bug description: PHP assumes MySQL unix socket is always available
Some pthread implementations (namely mit-pthreads, but
it might be problem also for other ones) don't support
unix sockets. Hence MySQL compiled using such threading
package does not use it. The code in php mysql
extension assumes that the unix socket is always available
on local machine (either when the host is not specified
in mysql_connect(), or it is "localhost"). This means
that it doesn't work when MySQL does not support
unix sockets.
I've implemented simple patch solving this issue.
This is fairly heavily tested on our company servers.
The patch changes the algorithm so that
if the unix socket would be used, code first checks
if it's available and fallbacks to TCP/IP if the unix
socket does not exists. The stat() is done only once
and the value is cached for further requests, so that
there should not be any performance problems caused
with this.
--- ext/mysql/libmysql/libmysql.c.orig Mon Mar 6 23:38:49 2000
+++ ext/mysql/libmysql/libmysql.c Wed Jul 19 12:48:15 2000
@@ -49,6 +49,7 @@ static my_bool mysql_client_init=0;
static MYSQL *current_mysql;
uint mysql_port=0;
my_string mysql_unix_port=0;
+static int mysql_socket_exists = -1;
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
@@ -1103,6 +1104,9 @@ mysql_real_connect(MYSQL *mysql,const ch
{
char buff[100],*end,*host_info;
int sock;
+#ifndef __WIN32__
+ int use_unix_socket = 0;
+#endif
ulong ip_addr;
struct sockaddr_in sock_addr;
uint pkt_length;
@@ -1165,11 +1169,37 @@ mysql_real_connect(MYSQL *mysql,const ch
*/
#if defined(HAVE_SYS_UN_H)
- if ((!host || !strcmp(host,LOCAL_HOST)) && (unix_socket || mysql_unix_port))
+ /*
+ * Check if we may use unix socket - some implementations of pthreads
+ * (such as mit-pthreads) don't support unix sockets, so MySQL compiled
+ * against such threading package doesn't use it even through it's configured
+ * to. So we have to check whether the unix socket file actually exists
+ * and use it only if it does.
+ * If caller passed unix socket path explicitly, allow override this
+ * check and write full error message to them later on.
+ */
+ if ((!host || strcmp(host,LOCAL_HOST) == 0)
+ && (unix_socket || (unix_socket = mysql_unix_port)))
+ {
+ if (host) {
+ /*
+ * Note this is thread-safe. Worst thing which would happen
+ * is that stat() would have chance to be called more than
+ * once here for brief period of time - not a big deal.
+ */
+ if (mysql_socket_exists < 0) {
+ struct stat sb;
+ mysql_socket_exists = (stat(unix_socket, &sb) == 0);
+ }
+
+ use_unix_socket = mysql_socket_exists;
+ } else
+ use_unix_socket = 1;
+ }
+
+ if (use_unix_socket)
{
host=LOCAL_HOST;
- if (!unix_socket)
- unix_socket=mysql_unix_port;
host_info=(char*) ER(CR_LOCALHOST_CONNECTION);
DBUG_PRINT("info",("Using UNIX sock '%s'",unix_socket));
if ((sock = socket(AF_UNIX,SOCK_STREAM,0)) == SOCKET_ERROR)