aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Modules/posixmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/posixmodule.c')
-rw-r--r--Modules/posixmodule.c105
1 files changed, 43 insertions, 62 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 04c3b9e987a..964e9888431 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -573,7 +573,11 @@ extern char *ctermid_r(char *);
# define HAVE_FACCESSAT_RUNTIME 1
# define HAVE_FCHMODAT_RUNTIME 1
# define HAVE_FCHOWNAT_RUNTIME 1
+#ifdef __wasi__
+# define HAVE_LINKAT_RUNTIME 0
+# else
# define HAVE_LINKAT_RUNTIME 1
+# endif
# define HAVE_FDOPENDIR_RUNTIME 1
# define HAVE_MKDIRAT_RUNTIME 1
# define HAVE_RENAMEAT_RUNTIME 1
@@ -4346,7 +4350,7 @@ os.link
*
src_dir_fd : dir_fd = None
dst_dir_fd : dir_fd = None
- follow_symlinks: bool = True
+ follow_symlinks: bool(c_default="-1", py_default="(os.name != 'nt')") = PLACEHOLDER
Create a hard link to a file.
@@ -4364,31 +4368,46 @@ src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
static PyObject *
os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
int dst_dir_fd, int follow_symlinks)
-/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
+/*[clinic end generated code: output=7f00f6007fd5269a input=1d5e602d115fed7b]*/
{
#ifdef MS_WINDOWS
BOOL result = FALSE;
#else
int result;
#endif
-#if defined(HAVE_LINKAT)
- int linkat_unavailable = 0;
-#endif
-#ifndef HAVE_LINKAT
- if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
- argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
- return NULL;
+#ifdef HAVE_LINKAT
+ if (HAVE_LINKAT_RUNTIME) {
+ if (follow_symlinks < 0) {
+ follow_symlinks = 1;
+ }
}
+ else
#endif
-
-#ifndef MS_WINDOWS
- if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
- PyErr_SetString(PyExc_NotImplementedError,
- "link: src and dst must be the same type");
- return NULL;
- }
+ {
+ if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
+ argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
+ return NULL;
+ }
+/* See issue 85527: link() on Linux works like linkat without AT_SYMLINK_FOLLOW,
+ but on Mac it works like linkat *with* AT_SYMLINK_FOLLOW. */
+#if defined(MS_WINDOWS) || defined(__linux__)
+ if (follow_symlinks == 1) {
+ argument_unavailable_error("link", "follow_symlinks=True");
+ return NULL;
+ }
+#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || (defined(__sun) && defined(__SVR4))
+ if (follow_symlinks == 0) {
+ argument_unavailable_error("link", "follow_symlinks=False");
+ return NULL;
+ }
+#else
+ if (follow_symlinks >= 0) {
+ argument_unavailable_error("link", "follow_symlinks");
+ return NULL;
+ }
#endif
+ }
if (PySys_Audit("os.link", "OOii", src->object, dst->object,
src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
@@ -4406,44 +4425,18 @@ os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
#else
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_LINKAT
- if ((src_dir_fd != DEFAULT_DIR_FD) ||
- (dst_dir_fd != DEFAULT_DIR_FD) ||
- (!follow_symlinks)) {
-
- if (HAVE_LINKAT_RUNTIME) {
-
- result = linkat(src_dir_fd, src->narrow,
- dst_dir_fd, dst->narrow,
- follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
-
- }
-#ifdef __APPLE__
- else {
- if (src_dir_fd == DEFAULT_DIR_FD && dst_dir_fd == DEFAULT_DIR_FD) {
- /* See issue 41355: This matches the behaviour of !HAVE_LINKAT */
- result = link(src->narrow, dst->narrow);
- } else {
- linkat_unavailable = 1;
- }
- }
-#endif
+ if (HAVE_LINKAT_RUNTIME) {
+ result = linkat(src_dir_fd, src->narrow,
+ dst_dir_fd, dst->narrow,
+ follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
}
else
-#endif /* HAVE_LINKAT */
+#endif
+ {
+ /* linkat not available */
result = link(src->narrow, dst->narrow);
- Py_END_ALLOW_THREADS
-
-#ifdef HAVE_LINKAT
- if (linkat_unavailable) {
- /* Either or both dir_fd arguments were specified */
- if (src_dir_fd != DEFAULT_DIR_FD) {
- argument_unavailable_error("link", "src_dir_fd");
- } else {
- argument_unavailable_error("link", "dst_dir_fd");
- }
- return NULL;
}
-#endif
+ Py_END_ALLOW_THREADS
if (result)
return path_error2(src, dst);
@@ -5935,12 +5928,6 @@ internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is
return path_error2(src, dst);
#else
- if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
- PyErr_Format(PyExc_ValueError,
- "%s: src and dst must be the same type", function_name);
- return NULL;
- }
-
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_RENAMEAT
if (dir_fd_specified) {
@@ -10613,12 +10600,6 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
#else
- if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
- PyErr_SetString(PyExc_ValueError,
- "symlink: src and dst must be the same type");
- return NULL;
- }
-
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_SYMLINKAT
if (dir_fd != DEFAULT_DIR_FD) {