PostgreSQL Source Code  git master
system.c
Go to the documentation of this file.
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-2024, 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 <fcntl.h>
48 
49 #undef system
50 #undef popen
51 
52 int
53 pgwin32_system(const char *command)
54 {
55  size_t cmdlen = strlen(command);
56  char *buf;
57  int save_errno;
58  int res;
59 
60  /*
61  * Create a malloc'd copy of the command string, enclosed with an extra
62  * pair of quotes
63  */
64  buf = malloc(cmdlen + 2 + 1);
65  if (buf == NULL)
66  {
67  errno = ENOMEM;
68  return -1;
69  }
70  buf[0] = '"';
71  memcpy(&buf[1], command, cmdlen);
72  buf[cmdlen + 1] = '"';
73  buf[cmdlen + 2] = '\0';
74 
75  res = system(buf);
76 
77  save_errno = errno;
78  free(buf);
79  errno = save_errno;
80 
81  return res;
82 }
83 
84 
85 FILE *
86 pgwin32_popen(const char *command, const char *type)
87 {
88  size_t cmdlen = strlen(command);
89  char *buf;
90  int save_errno;
91  FILE *res;
92 
93  /*
94  * Create a malloc'd copy of the command string, enclosed with an extra
95  * pair of quotes
96  */
97  buf = malloc(cmdlen + 2 + 1);
98  if (buf == NULL)
99  {
100  errno = ENOMEM;
101  return NULL;
102  }
103  buf[0] = '"';
104  memcpy(&buf[1], command, cmdlen);
105  buf[cmdlen + 1] = '"';
106  buf[cmdlen + 2] = '\0';
107 
108  res = _popen(buf, type);
109 
110  save_errno = errno;
111  free(buf);
112  errno = save_errno;
113 
114  return res;
115 }
116 
117 #endif
#define free(a)
Definition: header.h:65
#define malloc(a)
Definition: header.h:50
static char * buf
Definition: pg_test_fsync.c:72
const char * type