SpawnShellServer spawns a Shell server and forward input/output from/to the TCP socket.
(res *Response)
| 1338 | // SpawnShellServer spawns a Shell server and forward input/output from/to the |
| 1339 | // TCP socket. |
| 1340 | func (ghost *Ghost) SpawnShellServer(res *Response) error { |
| 1341 | log.Println("SpawnShellServer: started") |
| 1342 | |
| 1343 | var err error |
| 1344 | |
| 1345 | defer func() { |
| 1346 | ghost.quit = true |
| 1347 | if err != nil { |
| 1348 | if _, werr := ghost.Conn.Write([]byte(err.Error() + "\n")); werr != nil { |
| 1349 | log.Printf("Failed to write error to connection: %v", werr) |
| 1350 | } |
| 1351 | } |
| 1352 | ghost.Conn.Close() |
| 1353 | log.Println("SpawnShellServer: terminated") |
| 1354 | }() |
| 1355 | |
| 1356 | ghost.setupShellEnvironment() |
| 1357 | |
| 1358 | stopConn := make(chan struct{}) |
| 1359 | |
| 1360 | cmd, stdin, err := ghost.setupShellCommand(stopConn) |
| 1361 | if err != nil { |
| 1362 | return err |
| 1363 | } |
| 1364 | |
| 1365 | if err = cmd.Start(); err != nil { |
| 1366 | return err |
| 1367 | } |
| 1368 | |
| 1369 | defer ghost.cleanupShellProcess(cmd) |
| 1370 | |
| 1371 | stdinOpen := true |
| 1372 | for { |
| 1373 | select { |
| 1374 | case buf := <-ghost.readChan: |
| 1375 | if stdinOpen { |
| 1376 | ghost.handleShellInput(stdin, buf) |
| 1377 | } |
| 1378 | case err := <-ghost.readErrChan: |
| 1379 | if err == io.EOF { |
| 1380 | if stdinOpen { |
| 1381 | log.Println("SpawnShellServer: input EOF, closing stdin") |
| 1382 | stdin.Close() |
| 1383 | stdinOpen = false |
| 1384 | } |
| 1385 | // Continue waiting for subprocess to finish |
| 1386 | continue |
| 1387 | } |
| 1388 | log.Printf("SpawnShellServer: %s\n", err) |
| 1389 | return err |
| 1390 | case <-stopConn: |
| 1391 | return nil |
| 1392 | } |
| 1393 | } |
| 1394 | } |
| 1395 | |
| 1396 | // InitiatefileOperation initiates a file operation. |
| 1397 | // The operation could either be 'download' or 'upload' |
nothing calls this directly
no test coverage detected