@@ -7414,18 +7414,24 @@ If dir_fd is not None, it should be a file descriptor open to a directory,\n\
74147414 and path should be relative; path will then be relative to that directory.\n\
74157415dir_fd may not be implemented on your platform.\n\
74167416 If it is unavailable, using it will raise a NotImplementedError." );
7417- #endif
7418-
7419- #ifdef HAVE_READLINK
74207417
7421- /* AC 3.5: merge win32 and not together */
74227418static PyObject *
74237419posix_readlink (PyObject * self , PyObject * args , PyObject * kwargs )
74247420{
74257421 path_t path ;
74267422 int dir_fd = DEFAULT_DIR_FD ;
7423+ #if defined(HAVE_READLINK )
74277424 char buffer [MAXPATHLEN + 1 ];
74287425 ssize_t length ;
7426+ #elif defined(MS_WINDOWS )
7427+ DWORD n_bytes_returned ;
7428+ DWORD io_result ;
7429+ HANDLE reparse_point_handle ;
7430+
7431+ char target_buffer [_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE ];
7432+ _Py_REPARSE_DATA_BUFFER * rdb = (_Py_REPARSE_DATA_BUFFER * )target_buffer ;
7433+ const wchar_t * print_name ;
7434+ #endif
74297435 PyObject * return_value = NULL ;
74307436 static char * keywords [] = {"path" , "dir_fd" , NULL };
74317437
@@ -7436,6 +7442,7 @@ posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
74367442 READLINKAT_DIR_FD_CONVERTER , & dir_fd ))
74377443 return NULL ;
74387444
7445+ #if defined(HAVE_READLINK )
74397446 Py_BEGIN_ALLOW_THREADS
74407447#ifdef HAVE_READLINKAT
74417448 if (dir_fd != DEFAULT_DIR_FD )
@@ -7455,45 +7462,11 @@ posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
74557462 return_value = PyUnicode_DecodeFSDefaultAndSize (buffer , length );
74567463 else
74577464 return_value = PyBytes_FromStringAndSize (buffer , length );
7458- exit :
7459- path_cleanup (& path );
7460- return return_value ;
7461- }
7462-
7463- #endif /* HAVE_READLINK */
7464-
7465- #if !defined(HAVE_READLINK ) && defined(MS_WINDOWS )
7466-
7467- static PyObject *
7468- win_readlink (PyObject * self , PyObject * args , PyObject * kwargs )
7469- {
7470- const wchar_t * path ;
7471- DWORD n_bytes_returned ;
7472- DWORD io_result ;
7473- PyObject * po , * result ;
7474- int dir_fd ;
7475- HANDLE reparse_point_handle ;
7476-
7477- char target_buffer [_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE ];
7478- _Py_REPARSE_DATA_BUFFER * rdb = (_Py_REPARSE_DATA_BUFFER * )target_buffer ;
7479- const wchar_t * print_name ;
7480-
7481- static char * keywords [] = {"path" , "dir_fd" , NULL };
7482-
7483- if (!PyArg_ParseTupleAndKeywords (args , kwargs , "U|$O&:readlink" , keywords ,
7484- & po ,
7485- dir_fd_unavailable , & dir_fd
7486- ))
7487- return NULL ;
7488-
7489- path = _PyUnicode_AsUnicode (po );
7490- if (path == NULL )
7491- return NULL ;
7492-
7465+ #elif defined(MS_WINDOWS )
74937466 /* First get a handle to the reparse point */
74947467 Py_BEGIN_ALLOW_THREADS
74957468 reparse_point_handle = CreateFileW (
7496- path ,
7469+ path . wide ,
74977470 0 ,
74987471 0 ,
74997472 0 ,
@@ -7502,8 +7475,10 @@ win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
75027475 0 );
75037476 Py_END_ALLOW_THREADS
75047477
7505- if (reparse_point_handle == INVALID_HANDLE_VALUE )
7506- return win32_error_object ("readlink ", po );
7478+ if (reparse_point_handle == INVALID_HANDLE_VALUE ) {
7479+ return_value = path_error (& path );
7480+ goto exit ;
7481+ }
75077482
75087483 Py_BEGIN_ALLOW_THREADS
75097484 /* New call DeviceIoControl to read the reparse point */
@@ -7518,26 +7493,31 @@ win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
75187493 CloseHandle (reparse_point_handle );
75197494 Py_END_ALLOW_THREADS
75207495
7521- if (io_result == 0 )
7522- return win32_error_object ("readlink ", po );
7496+ if (io_result == 0 ) {
7497+ return_value = path_error (& path );
7498+ goto exit ;
7499+ }
75237500
75247501 if (rdb -> ReparseTag != IO_REPARSE_TAG_SYMLINK )
75257502 {
75267503 PyErr_SetString (PyExc_ValueError ,
75277504 "not a symbolic link" );
7528- return NULL ;
7505+ goto exit ;
75297506 }
75307507 print_name = (wchar_t * )((char * )rdb -> SymbolicLinkReparseBuffer .PathBuffer +
75317508 rdb -> SymbolicLinkReparseBuffer .PrintNameOffset );
75327509
7533- result = PyUnicode_FromWideChar (print_name ,
7534- rdb -> SymbolicLinkReparseBuffer .PrintNameLength / sizeof (wchar_t ));
7535- return result ;
7510+ return_value = PyUnicode_FromWideChar (print_name ,
7511+ rdb -> SymbolicLinkReparseBuffer .PrintNameLength / sizeof (wchar_t ));
7512+ if (path .narrow ) {
7513+ Py_SETREF (return_value , PyUnicode_EncodeFSDefault (return_value ));
7514+ }
7515+ #endif
7516+ exit :
7517+ path_cleanup (& path );
7518+ return return_value ;
75367519}
7537-
7538- #endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7539-
7540-
7520+ #endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
75417521
75427522#ifdef HAVE_SYMLINK
75437523
@@ -12950,16 +12930,11 @@ static PyMethodDef posix_methods[] = {
1295012930 OS_GETPRIORITY_METHODDEF
1295112931 OS_SETPRIORITY_METHODDEF
1295212932 OS_POSIX_SPAWN_METHODDEF
12953- #ifdef HAVE_READLINK
12933+ #if defined( HAVE_READLINK ) || defined ( MS_WINDOWS )
1295412934 {"readlink" , (PyCFunction )posix_readlink ,
1295512935 METH_VARARGS | METH_KEYWORDS ,
1295612936 readlink__doc__ },
12957- #endif /* HAVE_READLINK */
12958- #if !defined (HAVE_READLINK ) && defined (MS_WINDOWS )
12959- {"readlink" , (PyCFunction )win_readlink ,
12960- METH_VARARGS | METH_KEYWORDS ,
12961- readlink__doc__ },
12962- #endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
12937+ #endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
1296312938 OS_RENAME_METHODDEF
1296412939 OS_REPLACE_METHODDEF
1296512940 OS_RMDIR_METHODDEF
0 commit comments