Created
February 6, 2015 14:17
-
-
Save gawen/b376cb02f360205e7a1c to your computer and use it in GitHub Desktop.
Rename/Replace function behind "os.replace" in Python 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static PyObject * | |
internal_rename(PyObject *args, PyObject *kwargs, int is_replace) | |
{ | |
char *function_name = is_replace ? "replace" : "rename"; | |
path_t src; | |
path_t dst; | |
int src_dir_fd = DEFAULT_DIR_FD; | |
int dst_dir_fd = DEFAULT_DIR_FD; | |
int dir_fd_specified; | |
PyObject *return_value = NULL; | |
char format[24]; | |
static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; | |
#ifdef MS_WINDOWS | |
BOOL result; | |
int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0; | |
#else | |
int result; | |
#endif | |
memset(&src, 0, sizeof(src)); | |
memset(&dst, 0, sizeof(dst)); | |
src.function_name = function_name; | |
dst.function_name = function_name; | |
strcpy(format, "O&O&|$O&O&:"); | |
strcat(format, function_name); | |
if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords, | |
path_converter, &src, | |
path_converter, &dst, | |
dir_fd_converter, &src_dir_fd, | |
dir_fd_converter, &dst_dir_fd)) | |
return NULL; | |
dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) || | |
(dst_dir_fd != DEFAULT_DIR_FD); | |
#ifndef HAVE_RENAMEAT | |
if (dir_fd_specified) { | |
argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd"); | |
goto exit; | |
} | |
#endif | |
if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) { | |
PyErr_Format(PyExc_ValueError, | |
"%s: src and dst must be the same type", function_name); | |
goto exit; | |
} | |
#ifdef MS_WINDOWS | |
Py_BEGIN_ALLOW_THREADS | |
if (src.wide) | |
result = MoveFileExW(src.wide, dst.wide, flags); | |
else | |
result = MoveFileExA(src.narrow, dst.narrow, flags); | |
Py_END_ALLOW_THREADS | |
if (!result) { | |
return_value = path_error2(&src, &dst); | |
goto exit; | |
} | |
#else | |
Py_BEGIN_ALLOW_THREADS | |
#ifdef HAVE_RENAMEAT | |
if (dir_fd_specified) | |
result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow); | |
else | |
#endif | |
result = rename(src.narrow, dst.narrow); | |
Py_END_ALLOW_THREADS | |
if (result) { | |
return_value = path_error2(&src, &dst); | |
goto exit; | |
} | |
#endif | |
Py_INCREF(Py_None); | |
return_value = Py_None; | |
exit: | |
path_cleanup(&src); | |
path_cleanup(&dst); | |
return return_value; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment