summaryrefslogblamecommitdiffstats
path: root/src/main/java/org/openslx/satserver/util/Exec.java
blob: e27340961058a9e6a9cf9523f305da2255adc320 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                                   
                              

                           
                                 



                 


                                                                     
                                                                                  


                                               
                                                                                          
         
                                                                    

         





                                                                                                        
         
                                                                  
                                                

                                     

                                       













                                                                                   
                                          

                                          
                                                                  
                                  

















                                                                                                   
                 

         

























































                                                                                                                                  
 
package org.openslx.satserver.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

public class Exec
{

	/**
	 * Run command, return exit status of process, or -1 on error
	 * 
	 * @param timeoutSec maximum time in seconds to wait for process to finish
	 * @param command Command and arguments
	 * @return exit code
	 */
	public static int sync( int timeoutSec, ExecCallback callback, String... command )
	{
		return syncAt( timeoutSec, callback, "/", command );
	}

	public static int sync( int timeoutSec, String... command )
	{
		return sync( timeoutSec, null, command );
	}

	public static int syncAt( int timeoutSec, ExecCallback callback, String cwd, String... command )
	{
		ProcessBuilder pb = new ProcessBuilder( command );
		pb.directory( new File( cwd ) );
		Process p = null;
		Thread[] list = null;
		try {
			p = pb.start();
			if ( callback != null ) {
				list = setupCallback( p, callback );
			}
			if ( timeoutSec <= 0 ) {
				return p.waitFor();
			} else {
				for ( int i = 0; i < timeoutSec * 10; ++i ) {
					Thread.sleep( 100 );
					try {
						return p.exitValue();
					} catch ( IllegalThreadStateException e ) {
						// Wait...
					}
				}
				// Timeout
				return -1;
			}
		} catch ( IOException | InterruptedException e ) {
			return -2;
		} finally {
			try {
				if ( p != null ) {
					Util.multiClose( p.getOutputStream(), p.getErrorStream() );
					p.destroy();
				}
			} catch ( Exception e ) {
				//
			}
			if ( list != null ) {
				for ( Thread t : list ) {
					try {
						t.interrupt();
					} catch ( Exception e ) {
						//
					}
				}
			}
		}
	}

	public static int syncAt( int timeoutSec, String cwd, String... command )
	{
		return syncAt( timeoutSec, null, cwd, command );
	}

	private static Thread[] setupCallback( final Process p, final ExecCallback cb )
	{
		// Read its stdout
		Thread stdout = new Thread( new Runnable() {
			@Override
			public void run()
			{
				try {
					BufferedReader reader = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
					String line;
					while ( ( line = reader.readLine() ) != null ) {
						synchronized ( p ) {
							cb.processStdOut( line );
						}
					}
				} catch ( Exception e ) {
				}
			}
		} );
		// Read its stderr
		Thread stderr = new Thread( new Runnable() {
			@Override
			public void run()
			{
				try {
					BufferedReader reader = new BufferedReader( new InputStreamReader( p.getErrorStream() ) );
					String line;
					while ( ( line = reader.readLine() ) != null ) {
						synchronized ( p ) {
							cb.processStdErr( line );
						}
					}
				} catch ( Exception e ) {
				}
			}
		} );

		stdout.start();
		stderr.start();

		Thread[] t = new Thread[] { stdout, stderr };
		return t;
	}

	/**/

	public interface ExecCallback
	{
		public void processStdOut( String line );

		public void processStdErr( String line );
	}

}