@@ -1291,6 +1291,33 @@ static int doCmds(func_args* args)
12911291}
12921292
12931293
1294+ /* Resolve the CWD via RealPath (passing "." to get the current directory)
1295+ * and append the relative remote path into fullpath. WS_REKEYING and
1296+ * WS_WINDOW_FULL are intentionally excluded from the retry condition below;
1297+ * they require a wolfSSH_worker call that the caller's outer loop provides. */
1298+ static int doBuildRemotePath (const char * remote , char * fullpath , word32 fullpathSz ,
1299+ WS_SFTPNAME * * nameOut )
1300+ {
1301+ int err ;
1302+
1303+ if (remote == NULL || fullpath == NULL || fullpathSz == 0 || nameOut == NULL )
1304+ return WS_BAD_ARGUMENT ;
1305+ do {
1306+ * nameOut = wolfSSH_SFTP_RealPath (ssh , (char * )"." );
1307+ err = wolfSSH_get_error (ssh );
1308+ } while (err == WS_WANT_READ || err == WS_WANT_WRITE );
1309+ if (* nameOut == NULL )
1310+ return (err == WS_SUCCESS ) ? WS_FATAL_ERROR : err ;
1311+ if (snprintf (fullpath , fullpathSz , "%s/%s" , (* nameOut )-> fName , remote )
1312+ >= (int )fullpathSz ) {
1313+ wolfSSH_SFTPNAME_list_free (* nameOut );
1314+ * nameOut = NULL ;
1315+ return WS_FATAL_ERROR ;
1316+ }
1317+ return WS_SUCCESS ;
1318+ }
1319+
1320+
12941321/* alternate main loop for the autopilot get/receive */
12951322static int doAutopilot (int cmd , char * local , char * remote )
12961323{
@@ -1319,22 +1346,33 @@ static int doAutopilot(int cmd, char* local, char* remote)
13191346 WSTRNCPY (fullpath , remote , sizeof (fullpath ) - 1 );
13201347 }
13211348 else {
1322- do {
1323- name = wolfSSH_SFTP_RealPath (ssh , fullpath );
1324- err = wolfSSH_get_error (ssh );
1325- } while ((err == WS_WANT_READ || err == WS_WANT_WRITE ) &&
1326- ret != WS_SUCCESS );
1327-
1328- snprintf (fullpath , sizeof (fullpath ), "%s/%s" ,
1329- name == NULL ? "." : name -> fName ,
1330- remote );
1349+ err = doBuildRemotePath (remote , fullpath , sizeof (fullpath ), & name );
1350+ if (err != WS_SUCCESS && err != WS_REKEYING && err != WS_WINDOW_FULL )
1351+ return WS_FATAL_ERROR ;
13311352 }
13321353
13331354 do {
1334- if (err == WS_REKEYING || err == WS_WINDOW_FULL ) { /* handle rekeying state */
1355+ if (err == WS_REKEYING || err == WS_WINDOW_FULL ) { /* handle rekeying and window-full state */
13351356 do {
13361357 ret = wolfSSH_worker (ssh , NULL );
1337- } while (ret == WS_REKEYING );
1358+ } while (ret == WS_REKEYING || ret == WS_WINDOW_FULL ||
1359+ wolfSSH_get_error (ssh ) == WS_REKEYING );
1360+
1361+ /* wolfSSH_worker returns WS_FATAL_ERROR when the socket
1362+ * would block (DoReceive -> GetInputData -> WS_WANT_READ),
1363+ * so check ssh->error rather than ret for blocking conditions. */
1364+ if (ret != WS_SUCCESS && ret != WS_CHAN_RXD &&
1365+ wolfSSH_get_error (ssh ) != WS_WANT_READ &&
1366+ wolfSSH_get_error (ssh ) != WS_WANT_WRITE )
1367+ break ;
1368+
1369+ if (!remoteAbsPath && name == NULL ) {
1370+ err = doBuildRemotePath (remote , fullpath , sizeof (fullpath ), & name );
1371+ if (err != WS_SUCCESS ) {
1372+ ret = WS_FATAL_ERROR ;
1373+ continue ; /* skip wolfSSH_get_error; outer loop retries on err from doBuildRemotePath */
1374+ }
1375+ }
13381376 }
13391377
13401378 if (cmd == AUTOPILOT_PUT ) {
0 commit comments