Three patches from issue #1047, by Amaury Forgeot d'Arc:

1/ getargs.diff adds the 'Z' and 'Z#' format specifiers for
PyArg_ParseTuple. They mimic z and z# for unicode strings, by accepting
a Unicode or None (in which case the Py_UNICODE* pointer is set to
NULL). With doc and tests.

2/ subprocess.diff converts file PC/_subprocess.c to unicode. We use the
Unicode version of the win32 api (and Z conversion from previous patch)

3/ stdout.diff: sys.stdout must not convert the line endings, Windows
already does it.
Without this patch, when redirecting the output of python, the file
contains \r\r\n for each line. (test_subprocess did catch this)

However, I (GvR) removed the change to _fileio.c (included in the
patches) that prevents closing file descripors < 3 from being closed;
I think that needs to be solved in a different way.
This commit is contained in:
Guido van Rossum 2007-08-29 18:38:11 +00:00
parent e86254e256
commit fb67be2f6b
5 changed files with 118 additions and 32 deletions

View file

@ -35,9 +35,6 @@
/* Licensed to PSF under a Contributor Agreement. */
/* See http://www.python.org/2.4/license for licensing details. */
/* TODO: handle unicode command lines? */
/* TODO: handle unicode environment? */
#include "Python.h"
#define WINDOWS_LEAN_AND_MEAN
@ -272,7 +269,7 @@ gethandle(PyObject* obj, char* name)
PyErr_Clear(); /* FIXME: propagate error? */
return NULL;
}
if (Py_Type(&value) != &sp_handle_type)
if (Py_Type(value) != &sp_handle_type)
ret = NULL;
else
ret = value->handle;
@ -287,7 +284,7 @@ getenvironment(PyObject* environment)
PyObject* out = NULL;
PyObject* keys;
PyObject* values;
char* p;
Py_UNICODE* p;
/* convert environment dictionary to windows enviroment string */
if (! PyMapping_Check(environment)) {
@ -303,42 +300,42 @@ getenvironment(PyObject* environment)
if (!keys || !values)
goto error;
out = PyString_FromStringAndSize(NULL, 2048);
out = PyUnicode_FromUnicode(NULL, 2048);
if (! out)
goto error;
p = PyString_AS_STRING(out);
p = PyUnicode_AS_UNICODE(out);
for (i = 0; i < envsize; i++) {
int ksize, vsize, totalsize;
PyObject* key = PyList_GET_ITEM(keys, i);
PyObject* value = PyList_GET_ITEM(values, i);
if (! PyString_Check(key) || ! PyString_Check(value)) {
if (! PyUnicode_Check(key) || ! PyUnicode_Check(value)) {
PyErr_SetString(PyExc_TypeError,
"environment can only contain strings");
goto error;
}
ksize = PyString_GET_SIZE(key);
vsize = PyString_GET_SIZE(value);
totalsize = (p - PyString_AS_STRING(out)) + ksize + 1 +
ksize = PyUnicode_GET_SIZE(key);
vsize = PyUnicode_GET_SIZE(value);
totalsize = (p - PyUnicode_AS_UNICODE(out)) + ksize + 1 +
vsize + 1 + 1;
if (totalsize > PyString_GET_SIZE(out)) {
int offset = p - PyString_AS_STRING(out);
_PyString_Resize(&out, totalsize + 1024);
p = PyString_AS_STRING(out) + offset;
if (totalsize > PyUnicode_GET_SIZE(out)) {
int offset = p - PyUnicode_AS_UNICODE(out);
PyUnicode_Resize(&out, totalsize + 1024);
p = PyUnicode_AS_UNICODE(out) + offset;
}
memcpy(p, PyString_AS_STRING(key), ksize);
Py_UNICODE_COPY(p, PyUnicode_AS_UNICODE(key), ksize);
p += ksize;
*p++ = '=';
memcpy(p, PyString_AS_STRING(value), vsize);
Py_UNICODE_COPY(p, PyUnicode_AS_UNICODE(value), vsize);
p += vsize;
*p++ = '\0';
}
/* add trailing null byte */
*p++ = '\0';
_PyString_Resize(&out, p - PyString_AS_STRING(out));
PyUnicode_Resize(&out, p - PyUnicode_AS_UNICODE(out));
/* PyObject_Print(out, stdout, 0); */
@ -359,20 +356,20 @@ sp_CreateProcess(PyObject* self, PyObject* args)
{
BOOL result;
PROCESS_INFORMATION pi;
STARTUPINFO si;
STARTUPINFOW si;
PyObject* environment;
char* application_name;
char* command_line;
Py_UNICODE* application_name;
Py_UNICODE* command_line;
PyObject* process_attributes; /* ignored */
PyObject* thread_attributes; /* ignored */
int inherit_handles;
int creation_flags;
PyObject* env_mapping;
char* current_directory;
Py_UNICODE* current_directory;
PyObject* startup_info;
if (! PyArg_ParseTuple(args, "zzOOiiOzO:CreateProcess",
if (! PyArg_ParseTuple(args, "ZZOOiiOZO:CreateProcess",
&application_name,
&command_line,
&process_attributes,
@ -406,13 +403,13 @@ sp_CreateProcess(PyObject* self, PyObject* args)
}
Py_BEGIN_ALLOW_THREADS
result = CreateProcess(application_name,
result = CreateProcessW(application_name,
command_line,
NULL,
NULL,
inherit_handles,
creation_flags,
environment ? PyString_AS_STRING(environment) : NULL,
creation_flags | CREATE_UNICODE_ENVIRONMENT,
environment ? PyUnicode_AS_UNICODE(environment) : NULL,
current_directory,
&si,
&pi);
@ -504,18 +501,18 @@ sp_GetModuleFileName(PyObject* self, PyObject* args)
{
BOOL result;
long module;
TCHAR filename[MAX_PATH];
WCHAR filename[MAX_PATH];
if (! PyArg_ParseTuple(args, "l:GetModuleFileName", &module))
return NULL;
result = GetModuleFileName((HMODULE)module, filename, MAX_PATH);
result = GetModuleFileNameW((HMODULE)module, filename, MAX_PATH);
filename[MAX_PATH-1] = '\0';
if (! result)
return PyErr_SetFromWindowsErr(GetLastError());
return PyString_FromString(filename);
return PyUnicode_FromUnicode(filename, Py_UNICODE_strlen(filename));
}
static PyMethodDef sp_functions[] = {