1 /*-------------------------------------------------------------------------
2 *
3 * system.c
4 * Win32 system() and popen() replacements
5 *
6 *
7 * Win32 needs double quotes at the beginning and end of system()
8 * strings. If not, it gets confused with multiple quoted strings.
9 * It also requires double-quotes around the executable name and
10 * any files used for redirection. Filter other args through
11 * appendShellString() to quote them.
12 *
13 * Generated using Win32 "CMD /?":
14 *
15 * 1. If all of the following conditions are met, then quote characters
16 * on the command line are preserved:
17 *
18 * - no /S switch
19 * - exactly two quote characters
20 * - no special characters between the two quote characters, where special
21 * is one of: &<>()@^|
22 * - there are one or more whitespace characters between the two quote
23 * characters
24 * - the string between the two quote characters is the name of an
25 * executable file.
26 *
27 * 2. Otherwise, old behavior is to see if the first character is a quote
28 * character and if so, strip the leading character and remove the last
29 * quote character on the command line, preserving any text after the last
30 * quote character.
31 *
32 * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
33 *
34 * src/port/system.c
35 *
36 *-------------------------------------------------------------------------
37 */
38
39 #if defined(WIN32) && !defined(__CYGWIN__)
40
41 #ifndef FRONTEND
42 #include "postgres.h"
43 #else
44 #include "postgres_fe.h"
45 #endif
46
47 #include <windows.h>
48 #include <fcntl.h>
49
50 #undef system
51 #undef popen
52
53 int
pgwin32_system(const char * command)54 pgwin32_system(const char *command)
55 {
56 size_t cmdlen = strlen(command);
57 char *buf;
58 int save_errno;
59 int res;
60
61 /*
62 * Create a malloc'd copy of the command string, enclosed with an extra
63 * pair of quotes
64 */
65 buf = malloc(cmdlen + 2 + 1);
66 if (buf == NULL)
67 {
68 errno = ENOMEM;
69 return -1;
70 }
71 buf[0] = '"';
72 memcpy(&buf[1], command, cmdlen);
73 buf[cmdlen + 1] = '"';
74 buf[cmdlen + 2] = '\0';
75
76 res = system(buf);
77
78 save_errno = errno;
79 free(buf);
80 errno = save_errno;
81
82 return res;
83 }
84
85
86 FILE *
pgwin32_popen(const char * command,const char * type)87 pgwin32_popen(const char *command, const char *type)
88 {
89 size_t cmdlen = strlen(command);
90 char *buf;
91 int save_errno;
92 FILE *res;
93
94 /*
95 * Create a malloc'd copy of the command string, enclosed with an extra
96 * pair of quotes
97 */
98 buf = malloc(cmdlen + 2 + 1);
99 if (buf == NULL)
100 {
101 errno = ENOMEM;
102 return NULL;
103 }
104 buf[0] = '"';
105 memcpy(&buf[1], command, cmdlen);
106 buf[cmdlen + 1] = '"';
107 buf[cmdlen + 2] = '\0';
108
109 res = _popen(buf, type);
110
111 save_errno = errno;
112 free(buf);
113 errno = save_errno;
114
115 return res;
116 }
117
118 #endif
119