]> granicus.if.org Git - postgresql/blob - src/port/system.c
Introduce convenience macros to hide JsonbContainer header accesses better.
[postgresql] / src / port / system.c
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-2017, 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
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 *
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