nl_tokens: A process is running remotely on the Tessel and data is piped in over USB
pl_tokens: function USBProcess ( id , daemon ) { // The numerical identifer for this process this . id = id ; /*
    active && !closed = Process is running as usual
    !active && !closed = Process has been sent a signal but not completely closed (resources freed)
    !active && closed = Process has stopped running and has already been destroyed
    */ // Status of whether this process is running this . active = true ; // Status of whether this process was cleaned up this . closed = false ; // Boolean of whether this process has been forcibly killed this . forceKill = false ; // Code to be set upon process death this . exitedWithError = false ; // Some processes, like `sysupgrade` will not be close-able // because OpenWRT does not have the spidaemon active. // In these cases, just close without trying to send kill signal this . waitForClose = true ; // 4 remote process streams this . control = new RemoteWritableStream ( this , daemon , protocol . controlWrite , protocol . controlClose ) ; this . stdin = new RemoteWritableStream ( this , daemon , protocol . stdinWrite , protocol . stdinClose ) ; this . stdout = new RemoteReadableStream ( this , daemon , protocol . stdoutAck ) ; this . stderr = new RemoteReadableStream ( this , daemon , protocol . stderrAck ) ; // Once the process is killed this . once ( 'death' , ( data ) => { // This process is no longer running this . <mask> = false ; // Close the input streams because the remote proc can't handle data this . control . end ( ) ; this . stdin . end ( ) ; // Close the process this . closeProcessIfReady ( ) ; // Check for a non-zero exit code var exitCode = parseInt ( data . arg ) ; debug ( ` ${ this . commandString } ${ exitCode } ` ) ; if ( exitCode !== 0 && ! this . forceKill ) { this . exitedWithError = true ; } } ) ; // Tell the USBDaemon to close the remote process this . close = ( ) => { // Write the close command daemon . write ( protocol . closeProcess ( this . id ) ) ; // Mark this process as closed this . closed = true ; } ; // Send a signal to the remote process this . kill = ( signal ) => { // Mark our boolean this . forceKill = true ; // If we should wait for close (most processes should) if ( this . waitForClose ) { // Write the signal command daemon . write ( protocol . killProcess ( this . id , signal ) ) ; } else { // Mark the process as inactive and closed this . active = false ; this . closed = true ; // Emit the close event setImmediate ( ( ) => this . emit ( 'close' ) ) ; } } ; // Checks if this process is ready to be closed // and closes it if it can this . closeProcessIfReady = ( ) => { // If this process hasn't been closed before // and all of the streams are closed if ( ! this . active && ! this . closed && this . stdout . closed && this . stderr . closed ) { // Close this process this . close ( ) ; } } ; // When any of the streams complete, check if the process is ready to close this . stdout . once ( 'end' , ( ) => this . closeProcessIfReady ( ) ) ; this . stderr . once ( 'end' , ( ) => this . closeProcessIfReady ( ) ) ; // This function is primarily intended for compatibility with the ssh2 stream API this . stdout . signal = ( signalToSend ) => { switch ( signalToSend ) { case 'KILL' : this . kill ( 9 ) ; break ; case 'SIGINT' : this . kill ( 2 ) ; break ; } } ; // Tell the remote daemon that this process was created daemon . write ( protocol . newProcess ( this . id ) ) ; // Tell the remote daemon that we can start receiving outbound data this . stdout . ack ( MAX_BUFFER_SIZE ) ; this . stderr . ack ( MAX_BUFFER_SIZE ) ; }