Merge lp:~sergei.glushchenko/percona-server/5.5-BT34246-ps-blueprint-into-outfile-pipe-and-socket into lp:percona-server/5.5

Proposed by Sergei Glushchenko on 2013-08-20
Status: Merged
Approved by: Alexey Kopytov on 2013-09-20
Approved revision: 559
Merged at revision: 572
Proposed branch: lp:~sergei.glushchenko/percona-server/5.5-BT34246-ps-blueprint-into-outfile-pipe-and-socket
Merge into: lp:percona-server/5.5
Diff against target: 392 lines (+239/-14)
11 files modified
Percona-Server/include/my_dir.h (+2/-0)
Percona-Server/include/my_sys.h (+3/-0)
Percona-Server/include/mysql/psi/mysql_file.h (+44/-0)
Percona-Server/include/mysys_err.h (+4/-1)
Percona-Server/mysql-test/include/outfile_fifosocket.inc (+68/-0)
Percona-Server/mysql-test/r/percona_outfile_fifosocket.result (+12/-0)
Percona-Server/mysql-test/t/percona_outfile_fifosocket-master.opt (+1/-0)
Percona-Server/mysql-test/t/percona_outfile_fifosocket.test (+12/-0)
Percona-Server/mysys/errors.c (+7/-1)
Percona-Server/mysys/my_open.c (+53/-0)
Percona-Server/sql/sql_class.cc (+33/-12)
To merge this branch: bzr merge lp:~sergei.glushchenko/percona-server/5.5-BT34246-ps-blueprint-into-outfile-pipe-and-socket
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) Approve on 2013-09-20
George Ormond Lorch III g2 2013-08-20 Approve on 2013-09-05
Review via email: mp+181115@code.launchpad.net

Description of the change

This patch allows OUTFILE to write to fifo and unix socket.
fifo/socket should already be created in filesystem.
If file specified as OUTFILE exists server will check it's type.
If file is fifo, my_open will be used instead of my_create.
If file is socket, socket+conect will be used to connect to socket.
Both fifo and socken then will be worked with like an regular file.
If existing file is regular file, error will be thrown as it was before.

To post a comment you must log in.
review: Approve (g2)
Alexey Kopytov (akopytov) wrote :

Sergeim

   - the patch also allows using FIFOs/sockets with SELECT INTO
     DUMPFILE, rather than just SELECT INTO OUTFILE, but it’s not
     present anywhere in tests/MP/blueprint

   - please copy the MP description into the BP

   - Unix domain sockets are not supported on Windows, so all
     sockets-related code should be wrapped into #ifndef __WIN__

   - the test should also include inc/not_windows.inc

   - call to mysql_file_open() in create_file() does not need O_EXCL (it
     only makes sense together with O_CREAT which is not being passed)

   - if either mysql_file_open() or mysql_unix_socket_connect() return
     -1, create_file() assumes the file was neither a FIFO nor a socket
     and raises the ER_FILE_EXISTS_ERROR. Instead, it should not raise
     any errors (because it was already raised by one of those
     functions) and return -1.

   - if connect() fails in my_unix_socket_connect(), we return without
     closing the socket.

   - instead of doing:


  if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
    if (MyFlags & (MY_FAE | MY_WME))
      my_error(EE_CONNECT, MYF(0), FileName, errno);
    DBUG_RETURN(-1);
  }

  DBUG_RETURN(my_register_filename((File) sd, FileName, FILE_BY_OPEN,
           EE_FILENOTFOUND, MyFlags));

you could do:


  if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
    close(sd);
    sd= -1;
  }

  DBUG_RETURN(my_register_filename((File) sd, FileName, FILE_BY_OPEN,
           EE_CONNECT, MyFlags));

  - in the test case, the following Perl snippet creates a FIFO named
    ‘outfile’, but then the further code expects it to be named
    ‘fifo’:


perl;
use POSIX qw(mkfifo);
my $fn = "$ENV{'MYSQL_TMP_DIR'}/outfile";
unlink($fn);
mkfifo($fn, 0666) or die("mkfifo: $!");
EOF

--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
--send_eval SELECT 1,2,3 INTO OUTFILE '$MYSQL_TMP_DIR/fifo'

perl;
my $fn = "$ENV{'MYSQL_TMP_DIR'}/fifo";
open(FILE, $fn);
print(<FILE>);
close(FILE);
unlink($fn);
EOF

    The above only works because the second Perl snippet opens the file
    for reading and writing (i.e. creates a regular file named ‘fifo’)
    before SELECT INTO OUTFILE opens it. So we are testing SELECT INTO
    OUTFILE with a regular file here. Also, the second snippet is
    equivalent to:

--cat_file $MYSQL_TMP_DIR/fifo

  - the Unix domain socket test uses SLEEP() for synchronization. I
    understand it is tricky to avoid it in this case. But the following
    should work:

    1) create a procedure that would poll a certain file and execute
       SELECT INTO OUTFILE only when it is created:

CREATE PROCEDURE p1() BEGIN WHILE ISNULL(LOAD_FILE('$MYSQL_TMP_DIR/trigger')) DO SELECT SLEEP(1); END WHILE; SELECT 1,2,3 INTO OUTFILE '$MYSQL_TMP_DIR/socket'

    2) In Perl create that file before the listen() call:

open(FILE, '>', "$ENV{'MYSQL_TMP_DIR'}/trigger");
close(FILE);

review: Needs Fixing
Download full text (3.7 KiB)

Hi Alexey,

> Sergeim
>
> - the patch also allows using FIFOs/sockets with SELECT INTO
> DUMPFILE, rather than just SELECT INTO OUTFILE, but it’s not
> present anywhere in tests/MP/blueprint
>

I've mentioned it in both comments/MP and modified the test case to verify this behaviour. I think it's a feature rather than bug.

> - please copy the MP description into the BP
>
done.

> - Unix domain sockets are not supported on Windows, so all
> sockets-related code should be wrapped into #ifndef __WIN__
>

done.

> - the test should also include inc/not_windows.inc
>

done.

> - call to mysql_file_open() in create_file() does not need O_EXCL (it
> only makes sense together with O_CREAT which is not being passed)
>

right, it doesn't make sense. removed.

> - if either mysql_file_open() or mysql_unix_socket_connect() return
> -1, create_file() assumes the file was neither a FIFO nor a socket
> and raises the ER_FILE_EXISTS_ERROR. Instead, it should not raise
> any errors (because it was already raised by one of those
> functions) and return -1.
>

We need to raise ER_FILE_EXISTS_ERROR, in case when file exists and is not socket/fifo, but you're right that we did it also in the case of other errors. Fixed.

> - if connect() fails in my_unix_socket_connect(), we return without
> closing the socket.
>
> - instead of doing:
>
> —
> if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
> if (MyFlags & (MY_FAE | MY_WME))
> my_error(EE_CONNECT, MYF(0), FileName, errno);
> DBUG_RETURN(-1);
> }
>
> DBUG_RETURN(my_register_filename((File) sd, FileName, FILE_BY_OPEN,
> EE_FILENOTFOUND, MyFlags));
> —
>
> you could do:
>
> —
> if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
> close(sd);
> sd= -1;
> }
>
> DBUG_RETURN(my_register_filename((File) sd, FileName, FILE_BY_OPEN,
> EE_CONNECT, MyFlags));
> —
>

Done.

> - in the test case, the following Perl snippet creates a FIFO named
> ‘outfile’, but then the further code expects it to be named
> ‘fifo’:
>
> —
> perl;
> use POSIX qw(mkfifo);
> my $fn = "$ENV{'MYSQL_TMP_DIR'}/outfile";
> unlink($fn);
> mkfifo($fn, 0666) or die("mkfifo: $!");
> EOF
>
> --replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
> --send_eval SELECT 1,2,3 INTO OUTFILE '$MYSQL_TMP_DIR/fifo'
>
> perl;
> my $fn = "$ENV{'MYSQL_TMP_DIR'}/fifo";
> open(FILE, $fn);
> print(<FILE>);
> close(FILE);
> unlink($fn);
> EOF
> —
>
> The above only works because the second Perl snippet opens the file
> for reading and writing (i.e. creates a regular file named ‘fifo’)
> before SELECT INTO OUTFILE opens it. So we are testing SELECT INTO
> OUTFILE with a regular file here.

Fixed.

> Also, the second snippet is
> equivalent to:
>
> --cat_file $MYSQL_TMP_DIR/fifo
>

Replaced perl with cat_file.

> - the Unix domain socket test uses SLEEP() for synchronization. I
> understand it is tricky to avoid it in this case. But the following
> should work:
>
> 1) create a procedure that would poll a certain file and execute
> SELECT INTO OUTFILE only when i...

Read more...

Alexey Kopytov (akopytov) wrote :

MY_S_IFSOCK and MY_S_ISSOCK should also be inside #ifndef __WIN__ (Windows simply doesn't define S_IFSOCK). No need for another jenkins build.

review: Needs Fixing
Alexey Kopytov (akopytov) wrote :

It somehow didn't occur to me late in the evening that the constant will not be used anywhere. So please ignore the last comment.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Percona-Server/include/my_dir.h'
2--- Percona-Server/include/my_dir.h 2013-03-19 12:36:34 +0000
3+++ Percona-Server/include/my_dir.h 2013-09-19 16:14:11 +0000
4@@ -32,6 +32,7 @@
5 #define MY_S_IFBLK S_IFBLK /* block special */
6 #define MY_S_IFREG S_IFREG /* regular */
7 #define MY_S_IFIFO S_IFIFO /* fifo */
8+#define MY_S_IFSOCK S_IFSOCK /* socket */
9 #define MY_S_ISUID S_ISUID /* set user id on execution */
10 #define MY_S_ISGID S_ISGID /* set group id on execution */
11 #define MY_S_ISVTX S_ISVTX /* save swapped text even after use */
12@@ -44,6 +45,7 @@
13 #define MY_S_ISBLK(m) (((m) & MY_S_IFMT) == MY_S_IFBLK)
14 #define MY_S_ISREG(m) (((m) & MY_S_IFMT) == MY_S_IFREG)
15 #define MY_S_ISFIFO(m) (((m) & MY_S_IFMT) == MY_S_IFIFO)
16+#define MY_S_ISSOCK(m) (((m) & MY_S_IFMT) == MY_S_IFSOCK)
17
18 #define MY_DONT_SORT 512 /* my_lib; Don't sort files */
19 #define MY_WANT_STAT 1024 /* my_lib; stat files */
20
21=== modified file 'Percona-Server/include/my_sys.h'
22--- Percona-Server/include/my_sys.h 2013-06-27 15:35:20 +0000
23+++ Percona-Server/include/my_sys.h 2013-09-19 16:14:11 +0000
24@@ -562,6 +562,9 @@
25 extern char *my_once_strdup(const char *src,myf myflags);
26 extern void *my_once_memdup(const void *src, size_t len, myf myflags);
27 extern File my_open(const char *FileName,int Flags,myf MyFlags);
28+#ifndef __WIN__
29+extern File my_unix_socket_connect(const char *FileName,myf MyFlags);
30+#endif
31 extern File my_register_filename(File fd, const char *FileName,
32 enum file_type type_of_file,
33 uint error_message_number, myf MyFlags);
34
35=== modified file 'Percona-Server/include/mysql/psi/mysql_file.h'
36--- Percona-Server/include/mysql/psi/mysql_file.h 2010-12-21 12:00:26 +0000
37+++ Percona-Server/include/mysql/psi/mysql_file.h 2013-09-19 16:14:11 +0000
38@@ -303,6 +303,21 @@
39 #endif
40
41 /**
42+ @def mysql_unix_socket_connect(K, N, F)
43+ Instrumented open.
44+ @c mysql_unix_socket_connect connects to the unix domain socket.
45+*/
46+#ifndef __WIN__
47+#ifdef HAVE_PSI_INTERFACE
48+ #define mysql_unix_socket_connect(K, N, F) \
49+ inline_mysql_unix_socket_connect(K, __FILE__, __LINE__, N, F)
50+#else
51+ #define mysql_unix_socket_connect(K, N, F) \
52+ inline_mysql_unix_socket_connect(N, F)
53+#endif
54+#endif
55+
56+/**
57 @def mysql_file_close(FD, F)
58 Instrumented close.
59 @c mysql_file_close is a replacement for @c my_close.
60@@ -1051,6 +1066,35 @@
61 return file;
62 }
63
64+#ifndef __WIN__
65+static inline File
66+inline_mysql_unix_socket_connect(
67+#ifdef HAVE_PSI_INTERFACE
68+ PSI_file_key key, const char *src_file, uint src_line,
69+#endif
70+ const char *filename, myf myFlags)
71+{
72+ File file;
73+#ifdef HAVE_PSI_INTERFACE
74+ struct PSI_file_locker *locker= NULL;
75+ PSI_file_locker_state state;
76+ if (likely(PSI_server != NULL))
77+ {
78+ locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_OPEN,
79+ filename, &locker);
80+ if (likely(locker != NULL))
81+ PSI_server->start_file_open_wait(locker, src_file, src_line);
82+ }
83+#endif
84+ file = my_unix_socket_connect(filename, myFlags);
85+#ifdef HAVE_PSI_INTERFACE
86+ if (likely(locker != NULL))
87+ PSI_server->end_file_open_wait_and_bind_to_descriptor(locker, file);
88+#endif
89+ return file;
90+}
91+#endif
92+
93 static inline int
94 inline_mysql_file_close(
95 #ifdef HAVE_PSI_INTERFACE
96
97=== modified file 'Percona-Server/include/mysys_err.h'
98--- Percona-Server/include/mysys_err.h 2011-06-30 15:46:53 +0000
99+++ Percona-Server/include/mysys_err.h 2013-09-19 16:14:11 +0000
100@@ -66,7 +66,10 @@
101 #define EE_CHANGE_OWNERSHIP 31
102 #define EE_CHANGE_PERMISSIONS 32
103 #define EE_CANT_SEEK 33
104-#define EE_ERROR_LAST 33 /* Copy last error nr */
105+#define EE_SOCKET 34
106+#define EE_CONNECT 35
107+#define EE_TOOLONGFILENAME 36
108+#define EE_ERROR_LAST 36 /* Copy last error nr */
109 /* Add error numbers before EE_ERROR_LAST and change it accordingly. */
110
111 /* exit codes for all MySQL programs */
112
113=== added file 'Percona-Server/mysql-test/include/outfile_fifosocket.inc'
114--- Percona-Server/mysql-test/include/outfile_fifosocket.inc 1970-01-01 00:00:00 +0000
115+++ Percona-Server/mysql-test/include/outfile_fifosocket.inc 2013-09-19 16:14:11 +0000
116@@ -0,0 +1,68 @@
117+#
118+# Test SELECT INTO OUTFILE/DUMPFILE with fifo and unix socket as destination
119+#
120+
121+perl;
122+my $fn = "$ENV{'MYSQL_TMP_DIR'}/regular";
123+unlink($fn);
124+open(FILE, ">$fn");
125+print(FILE "1\n");
126+close(FILE);
127+EOF
128+
129+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
130+--error 1086
131+--eval SELECT 1,2,3 INTO $select_into '$MYSQL_TMP_DIR/regular'
132+
133+perl;
134+use POSIX qw(mkfifo);
135+my $fn = "$ENV{'MYSQL_TMP_DIR'}/fifo";
136+unlink($fn);
137+mkfifo($fn, 0666) or die("mkfifo: $!");
138+EOF
139+
140+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
141+--send_eval SELECT 1,2,3 INTO $select_into '$MYSQL_TMP_DIR/fifo'
142+
143+--cat_file $MYSQL_TMP_DIR/fifo
144+
145+--reap
146+
147+DELIMITER //;
148+# procedure spin waiting when file 'trigger' appears
149+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
150+--eval CREATE PROCEDURE p1() BEGIN WHILE ISNULL(LOAD_FILE('$MYSQL_TMP_DIR/trigger')) DO SELECT SLEEP(1); END WHILE; SELECT 1,2,3 INTO $select_into '$MYSQL_TMP_DIR/socket'; END
151+DELIMITER ;//
152+
153+--send CALL p1()
154+
155+perl;
156+use Socket;
157+use IO::Handle;
158+
159+my $fn = "$ENV{'MYSQL_TMP_DIR'}/socket";
160+my $trigger = "$ENV{'MYSQL_TMP_DIR'}/trigger";
161+
162+unlink($fn);
163+socket(SERV, PF_UNIX, SOCK_STREAM, 0) or die("socket: $!");
164+bind(SERV, sockaddr_un($fn)) or die("bind $fn: $!");
165+
166+# tell the p1 that we created the socket
167+open(FILE, ">$trigger");
168+close(FILE);
169+
170+listen(SERV, 1) or die("listen: $!");
171+
172+accept(CLIENT, SERV);
173+$content = <CLIENT>;
174+close(CLIENT);
175+close(SERV);
176+unlink($fn);
177+unlink($trigger);
178+
179+EOF
180+
181+--disable_result_log
182+--reap
183+
184+DROP PROCEDURE p1;
185
186=== added file 'Percona-Server/mysql-test/r/percona_outfile_fifosocket.result'
187--- Percona-Server/mysql-test/r/percona_outfile_fifosocket.result 1970-01-01 00:00:00 +0000
188+++ Percona-Server/mysql-test/r/percona_outfile_fifosocket.result 2013-09-19 16:14:11 +0000
189@@ -0,0 +1,12 @@
190+SELECT 1,2,3 INTO OUTFILE 'MYSQL_TMP_DIR/regular';
191+ERROR HY000: File 'MYSQL_TMP_DIR/regular' already exists
192+SELECT 1,2,3 INTO OUTFILE 'MYSQL_TMP_DIR/fifo';
193+1 2 3
194+CREATE PROCEDURE p1() BEGIN WHILE ISNULL(LOAD_FILE('MYSQL_TMP_DIR/trigger')) DO SELECT SLEEP(1); END WHILE; SELECT 1,2,3 INTO OUTFILE 'MYSQL_TMP_DIR/socket'; END//
195+CALL p1();
196+DROP PROCEDURE p1;
197+SELECT 1,2,3 INTO DUMPFILE 'MYSQL_TMP_DIR/regular';
198+SELECT 1,2,3 INTO DUMPFILE 'MYSQL_TMP_DIR/fifo';
199+123CREATE PROCEDURE p1() BEGIN WHILE ISNULL(LOAD_FILE('MYSQL_TMP_DIR/trigger')) DO SELECT SLEEP(1); END WHILE; SELECT 1,2,3 INTO DUMPFILE 'MYSQL_TMP_DIR/socket'; END//
200+CALL p1();
201+DROP PROCEDURE p1;
202
203=== added file 'Percona-Server/mysql-test/t/percona_outfile_fifosocket-master.opt'
204--- Percona-Server/mysql-test/t/percona_outfile_fifosocket-master.opt 1970-01-01 00:00:00 +0000
205+++ Percona-Server/mysql-test/t/percona_outfile_fifosocket-master.opt 2013-09-19 16:14:11 +0000
206@@ -0,0 +1,1 @@
207+--secure_file_priv=$MYSQL_TMP_DIR
208
209=== added file 'Percona-Server/mysql-test/t/percona_outfile_fifosocket.test'
210--- Percona-Server/mysql-test/t/percona_outfile_fifosocket.test 1970-01-01 00:00:00 +0000
211+++ Percona-Server/mysql-test/t/percona_outfile_fifosocket.test 2013-09-19 16:14:11 +0000
212@@ -0,0 +1,12 @@
213+#
214+# Test that it is possible to specify fifos and unix sockets as
215+# an outfile
216+#
217+
218+--source include/not_windows.inc
219+
220+--let $select_into=OUTFILE
221+--source include/outfile_fifosocket.inc
222+
223+--let $select_into=DUMPFILE
224+--source include/outfile_fifosocket.inc
225
226=== modified file 'Percona-Server/mysys/errors.c'
227--- Percona-Server/mysys/errors.c 2013-03-01 09:31:32 +0000
228+++ Percona-Server/mysys/errors.c 2013-09-19 16:14:11 +0000
229@@ -52,7 +52,10 @@
230 "File '%s' (fileno: %d) was not closed",
231 "Can't change ownership of the file '%s' (Errcode: %d)",
232 "Can't change permissions of the file '%s' (Errcode: %d)",
233- "Can't seek in file '%s' (Errcode: %d)"
234+ "Can't seek in file '%s' (Errcode: %d)",
235+ "Can't create socket '%s' (Errcode: %d)",
236+ "Can't connect to '%s' (Errcode: %d)",
237+ "File name '%s' is too long (max: %d)"
238 };
239
240 void init_glob_errs(void)
241@@ -96,6 +99,9 @@
242 EE(EE_CHANGE_OWNERSHIP) = "Can't change ownership of the file '%s' (Errcode: %d)";
243 EE(EE_CHANGE_PERMISSIONS) = "Can't change permissions of the file '%s' (Errcode: %d)";
244 EE(EE_CANT_SEEK) = "Can't seek in file '%s' (Errcode: %d)";
245+ EE(EE_SOCKET) = "Can't create socket '%s' (Errcode: %d)";
246+ EE(EE_CONNECT) = "Can't connect to '%s' (Errcode: %d)";
247+ EE(EE_TOOLONGFILENAME) = "File name '%s' is too long (max: %d)";
248 }
249 #endif
250
251
252=== modified file 'Percona-Server/mysys/my_open.c'
253--- Percona-Server/mysys/my_open.c 2013-03-19 12:36:34 +0000
254+++ Percona-Server/mysys/my_open.c 2013-09-19 16:14:11 +0000
255@@ -17,6 +17,9 @@
256 #include "mysys_err.h"
257 #include <my_dir.h>
258 #include <errno.h>
259+#ifdef HAVE_SYS_UN_H
260+#include <sys/un.h>
261+#endif
262
263
264 /*
265@@ -55,6 +58,56 @@
266
267
268 /*
269+ Connect to unix domain socket
270+
271+ SYNOPSIS
272+ my_unix_socket_connect()
273+ FileName Fully qualified file name
274+ MyFlags Special flags
275+
276+ RETURN VALUE
277+ File descriptor
278+*/
279+
280+#ifndef __WIN__
281+File my_unix_socket_connect(const char *FileName, myf MyFlags)
282+ /* Path-name of file */
283+ /* Read | write .. */
284+ /* Special flags */
285+{
286+ my_socket sd;
287+ struct sockaddr_un addr;
288+ DBUG_ENTER("my_unix_socket_connect");
289+ DBUG_PRINT("my",("Name: '%s' MyFlags: %d",
290+ FileName, MyFlags));
291+
292+ if (strlen(FileName) > (sizeof(addr.sun_path) - 1))
293+ {
294+ if (MyFlags & (MY_FAE | MY_WME))
295+ my_error(EE_TOOLONGFILENAME, MYF(0), FileName, sizeof(addr.sun_path) - 1);
296+ DBUG_RETURN(-1);
297+ }
298+ if ((sd= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
299+ {
300+ if (MyFlags & (MY_FAE | MY_WME))
301+ my_error(EE_SOCKET, MYF(0), FileName, errno);
302+ DBUG_RETURN(-1);
303+ }
304+ memset(&addr, 0, sizeof(addr));
305+ addr.sun_family = AF_UNIX;
306+ strcpy(addr.sun_path, FileName);
307+ if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
308+ close(sd);
309+ sd= -1;
310+ }
311+
312+ DBUG_RETURN(my_register_filename((File) sd, FileName, FILE_BY_OPEN,
313+ EE_FILENOTFOUND, MyFlags));
314+} /* my_unix_socket_connect */
315+#endif
316+
317+
318+/*
319 Close a file
320
321 SYNOPSIS
322
323=== modified file 'Percona-Server/sql/sql_class.cc'
324--- Percona-Server/sql/sql_class.cc 2013-08-02 09:40:55 +0000
325+++ Percona-Server/sql/sql_class.cc 2013-09-19 16:14:11 +0000
326@@ -2490,7 +2490,10 @@
327 static File create_file(THD *thd, char *path, sql_exchange *exchange,
328 IO_CACHE *cache)
329 {
330- File file;
331+ File file= -1;
332+ bool new_file_created= false;
333+ MY_STAT stat_arg;
334+
335 uint option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
336
337 #ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
338@@ -2513,25 +2516,43 @@
339 return -1;
340 }
341
342- if (!access(path, F_OK))
343+ if (my_stat(path, &stat_arg, MYF(0)))
344 {
345- my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
346- return -1;
347+ /* Check if file is named pipe or unix socket */
348+ if (MY_S_ISFIFO(stat_arg.st_mode))
349+ file= mysql_file_open(key_select_to_file,
350+ path, O_WRONLY, MYF(MY_WME));
351+#ifndef __WIN__
352+ if (MY_S_ISSOCK(stat_arg.st_mode))
353+ file= mysql_unix_socket_connect(key_select_to_file,
354+ path, MYF(MY_WME));
355+#endif
356+ if (file < 0)
357+ {
358+ if (!(MY_S_ISFIFO(stat_arg.st_mode) || MY_S_ISSOCK(stat_arg.st_mode)))
359+ my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
360+ return -1;
361+ }
362 }
363- /* Create the file world readable */
364- if ((file= mysql_file_create(key_select_to_file,
365- path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
366- return file;
367+ else
368+ {
369+ /* Create the file world readable */
370+ if ((file= mysql_file_create(key_select_to_file,
371+ path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
372+ return file;
373+ new_file_created= true;
374 #ifdef HAVE_FCHMOD
375- (void) fchmod(file, 0666); // Because of umask()
376+ (void) fchmod(file, 0666); // Because of umask()
377 #else
378- (void) chmod(path, 0666);
379+ (void) chmod(path, 0666);
380 #endif
381+ }
382 if (init_io_cache(cache, file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME)))
383 {
384 mysql_file_close(file, MYF(0));
385- /* Delete file on error, it was just created */
386- mysql_file_delete(key_select_to_file, path, MYF(0));
387+ /* Delete file on error, if it was just created */
388+ if (new_file_created)
389+ mysql_file_delete(key_select_to_file, path, MYF(0));
390 return -1;
391 }
392 return file;

Subscribers

People subscribed via source and target branches