2008-12-18 29 views
6

Estaba pirateando el código fuente de plink para que sea compatible con Unison.

Si no sabe, el unísono es una herramienta de sincronización de archivos, ejecuta un comando "ssh" para conectarse a un servidor remoto, pero no hay ssh.exe para Windows; hay plink, que está muy cerca pero no lo suficientemente cerca (no se comporta como lo espera el unísono), por lo que la gente generalmente hace envoltorios alrededor, like this one.

uno de los problemas es que unison espera que la solicitud de contraseña se imprima en stderr (pero plink lo imprime en stdout, y hace que el unísono se confunda), así que pensé, bien, debería ser lo suficientemente simple, hackear a través de plink codificar y hacer que imprima el mensaje de salida estándar. así que me abrí paso y lo hice.

Siguiente problema: ¡No puedo responder al aviso! no importa lo que escriba, no tiene ningún efecto.

el código para conseguir la entrada es más o menos así:

hin = GetStdHandle(STD_INPUT_HANDLE); 
.... 
r = ReadFile(hin, .....); 

No estoy seguro de por qué se hace de esta manera, pero no soy un experto en el diseño de herramientas de línea de comandos para las ventanas, así que lo que hacen ¡Lo sé! Pero creo que falta algo en la configuración del control de entrada.

Miré el código fuente para el above wrapper tool y veo esto: hconin=CreateFile("CONIN$",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,0,0)

y lo intento (sólo por el gusto de hacerlo)

hin=CreateFile("CONIN$",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,0,0); 
.... 
r = ReadFile(hin ......) 

y, sorprendentemente, funciona! ¡Ahora puedo responder al aviso!

¿Por qué es esto? ¿Qué es "CONIN $"? y por qué es diferente de STD_INPUT_HANDLE?

puedo especie de "adivinar" que FILE_SHARE_READ y OPEN_EXISTING están jugando un papel en esto (ya que ssh se ejecuta desde dentro de otro proceso), pero quiero entender lo que está pasando aquí, y asegúrese de que el código doesn ¡Tiene algunos efectos secundarios no deseados o agujeros de seguridad o algo así de aterrador!

Respuesta

10

CONIN$ es el dispositivo de entrada de la consola. Normalmente, stdin es un archivo abierto para manejar esto, pero si stdin se redirige por alguna razón, entonces usar CONIN$ le permitirá acceder a la consola a pesar de la redirección. Reference.

+0

Es como abrir/dev/console en Unix. :-) –

+1

Se parece más a '/ dev/tty', que apunta al terminal de control del proceso, mientras que'/dev/console' es generalmente la consola física (serial o tty1). – grawity

+0

@Andrew: ¿De verdad? Si redirigió stdin, '/ dev/stdin' aparecerá en el archivo redirigido. Pensé que se suponía que 'CONIN $' llegaría a la terminal, independientemente de cualquier redirección. –