summaryrefslogtreecommitdiffstats
path: root/src/port/system.c
blob: b6d13694fedad55b828dd4b8b60a38250dc53c71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*-------------------------------------------------------------------------
 *
 * system.c
 *	   Win32 system() and popen() replacements
 *
 *
 *	Win32 needs double quotes at the beginning and end of system()
 *	strings.  If not, it gets confused with multiple quoted strings.
 *	It also requires double-quotes around the executable name and
 *	any files used for redirection.  Filter other args through
 *	appendShellString() to quote them.
 *
 *	Generated using Win32 "CMD /?":
 *
 *	1. If all of the following conditions are met, then quote characters
 *	on the command line are preserved:
 *
 *	 - no /S switch
 *	 - exactly two quote characters
 *	 - no special characters between the two quote characters, where special
 *	   is one of: &<>()@^|
 *	 - there are one or more whitespace characters between the two quote
 *	   characters
 *	 - the string between the two quote characters is the name of an
 *	   executable file.
 *
 *	 2. Otherwise, old behavior is to see if the first character is a quote
 *	 character and if so, strip the leading character and remove the last
 *	 quote character on the command line, preserving any text after the last
 *	 quote character.
 *
 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
 *
 * src/port/system.c
 *
 *-------------------------------------------------------------------------
 */

#if defined(WIN32) && !defined(__CYGWIN__)

#ifndef FRONTEND
#include "postgres.h"
#else
#include "postgres_fe.h"
#endif

#include <fcntl.h>

#undef system
#undef popen

int
pgwin32_system(const char *command)
{
	size_t		cmdlen = strlen(command);
	char	   *buf;
	int			save_errno;
	int			res;

	/*
	 * Create a malloc'd copy of the command string, enclosed with an extra
	 * pair of quotes
	 */
	buf = malloc(cmdlen + 2 + 1);
	if (buf == NULL)
	{
		errno = ENOMEM;
		return -1;
	}
	buf[0] = '"';
	memcpy(&buf[1], command, cmdlen);
	buf[cmdlen + 1] = '"';
	buf[cmdlen + 2] = '\0';

	res = system(buf);

	save_errno = errno;
	free(buf);
	errno = save_errno;

	return res;
}


FILE *
pgwin32_popen(const char *command, const char *type)
{
	size_t		cmdlen = strlen(command);
	char	   *buf;
	int			save_errno;
	FILE	   *res;

	/*
	 * Create a malloc'd copy of the command string, enclosed with an extra
	 * pair of quotes
	 */
	buf = malloc(cmdlen + 2 + 1);
	if (buf == NULL)
	{
		errno = ENOMEM;
		return NULL;
	}
	buf[0] = '"';
	memcpy(&buf[1], command, cmdlen);
	buf[cmdlen + 1] = '"';
	buf[cmdlen + 2] = '\0';

	res = _popen(buf, type);

	save_errno = errno;
	free(buf);
	errno = save_errno;

	return res;
}

#endif