I'm trying to find where in CPython's implementation execv is implemented. I've found this commit from Guido where he adds it back in 1993, but the commit does not show where execv comes from.
1 Answer
From help(os.execv):
Help on built-in function execv in module posix:
execv(path, argv, /) Execute an executable path with arguments, replacing current process.
path Path of executable file. argv Tuple or list of strings.
It's defined in posix, which is a c module to wrap unix functions. The snippet you are probably looking for is here:
#ifdef HAVE_EXECV
/*[clinic input]
os.execv
path: path_t
Path of executable file.
argv: object
Tuple or list of strings.
/
Execute an executable path with arguments, replacing current process.
[clinic start generated code]*/
static PyObject *
os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
{
EXECV_CHAR **argvlist;
Py_ssize_t argc;
/* execv has two arguments: (path, argv), where
argv is a list or tuple of strings. */
if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
PyErr_SetString(PyExc_TypeError,
"execv() arg 2 must be a tuple or list");
return NULL;
}
argc = PySequence_Size(argv);
if (argc < 1) {
PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
return NULL;
}
argvlist = parse_arglist(argv, &argc);
if (argvlist == NULL) {
return NULL;
}
if (!argvlist[0][0]) {
PyErr_SetString(PyExc_ValueError,
"execv() arg 2 first element cannot be empty");
free_string_array(argvlist, argc);
return NULL;
}
if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) {
free_string_array(argvlist, argc);
return NULL;
}
_Py_BEGIN_SUPPRESS_IPH
#ifdef HAVE_WEXECV
_wexecv(path->wide, argvlist);
#else
execv(path->narrow, argvlist);
#endif
_Py_END_SUPPRESS_IPH
/* If we get here it's definitely an error */
free_string_array(argvlist, argc);
return posix_error();
}
2 Comments
luizbarcelos
Just a quick follow up question before marking as accepted, do you know where
execv goes right after the #else macro in that snippet? Thanks, that's exactly what I wanted.C.Nivs
@luizbarcelos Unfortunately, my c is not great. Best I can tell is that if
HAVE_WEXECV or HAVE_EXECV is defined, then python is being used within the windows runtime and only certain unix functions may be available and a wrapper is explicitly defined. Otherwise, os can just directly call into the execv function due to clinic generating the boilerplate. My understanding here is pretty thin, so take this comment with a hefty pinch of salt