Source Code Cross Referenced for ExecCmd.java in  » Scripting » jacl » tcl » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » jacl » tcl.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * ExecCmd.java --
003:         *
004:         *	This file contains the Jacl implementation of the built-in Tcl "exec"
005:         *	command. The exec command is not available on the Mac.
006:         *
007:         * Copyright (c) 1997 Sun Microsystems, Inc.
008:         *
009:         * See the file "license.terms" for information on usage and
010:         * redistribution of this file, and for a DISCLAIMER OF ALL
011:         * WARRANTIES.
012:         * 
013:         * RCS: @(#) $Id: ExecCmd.java,v 1.13 2006/06/30 07:57:18 mdejong Exp $
014:         */
015:
016:        package tcl.lang;
017:
018:        import java.util.*;
019:        import java.io.*;
020:
021:        /*
022:         * This class implements the built-in "exec" command in Tcl.
023:         */
024:
025:        class ExecCmd implements  Command {
026:
027:            private static boolean debug = false;
028:
029:            /*
030:             *----------------------------------------------------------------------
031:             *
032:             * cmdProc --
033:             *
034:             *	This procedure is invoked to process the "exec" Tcl command.
035:             *	See the user documentation for details on what it does.
036:             *
037:             * Results:
038:             *	None.
039:             *
040:             * Side effects:
041:             *	See the user documentation.
042:             *
043:             *----------------------------------------------------------------------
044:             */
045:
046:            public void cmdProc(Interp interp, // The current interpreter.
047:                    TclObject argv[]) // The arguments to exec.
048:                    throws TclException // A standard Tcl exception.
049:            {
050:                int firstWord; // Index to the first non-switch arg
051:                int argLen = argv.length; // No of args to copy to argStrs
052:                int exit; // denotes exit status of process
053:                int errorBytes; // number of bytes of process stderr
054:                boolean background = false; // Indicates a bg process
055:                boolean keepNewline = false; // Retains newline in pipline output
056:                Process p; // The exec-ed process
057:                String argStr; // Conversion of argv to a string
058:                StringBuffer sbuf;
059:
060:                // Check for a leading "-keepnewline" argument.
061:
062:                for (firstWord = 1; firstWord < argLen; firstWord++) {
063:                    argStr = argv[firstWord].toString();
064:                    if ((argStr.length() > 0) && (argStr.charAt(0) == '-')) {
065:                        if (argStr.equals("-keepnewline")) {
066:                            keepNewline = true;
067:                        } else if (argStr.equals("--")) {
068:                            firstWord++;
069:                            break;
070:                        } else {
071:                            throw new TclException(interp, "bad switch \""
072:                                    + argStr + "\": must be -keepnewline or --");
073:                        }
074:                    } else {
075:                        break;
076:                    }
077:                }
078:
079:                if (argLen <= firstWord) {
080:                    throw new TclNumArgsException(interp, 1, argv,
081:                            "?switches? arg ?arg ...?");
082:                }
083:
084:                // See if the command is to be run in background.
085:                // Currently this does nothing, it is just for compatibility
086:
087:                if (argv[argLen - 1].toString().equals("&")) {
088:                    argLen--;
089:                    background = true;
090:                }
091:
092:                try {
093:                    p = execCmd(interp, argv, firstWord, argLen);
094:
095:                    // If user wanted to run in the background, then
096:                    // don't wait for or attach to the stdout or stderr
097:                    // streams. We don't actually know what the pid is
098:                    // so just return a placeholder.
099:
100:                    if (background) {
101:                        interp.setResult("pid0");
102:                        return;
103:                    }
104:
105:                    sbuf = new StringBuffer();
106:
107:                    // Create a pair of threads to read stdout and stderr
108:                    // of the subprocess. Each stream needs to be handled
109:                    // by a serarate thread.
110:
111:                    ExecInputStreamReader stdout_reader = new ExecInputStreamReader(
112:                            p.getInputStream());
113:
114:                    ExecInputStreamReader stderr_reader = new ExecInputStreamReader(
115:                            p.getErrorStream());
116:
117:                    // Start reading threads, wait for process to terminate in
118:                    // this thread, then make sure other threads have terminated.
119:
120:                    stdout_reader.start();
121:                    stderr_reader.start();
122:
123:                    if (debug) {
124:                        System.out
125:                                .println("started reader threads, invoking waitFor()");
126:                    }
127:
128:                    exit = p.waitFor();
129:
130:                    if (debug) {
131:                        System.out.println("waitFor() returned " + exit);
132:                        System.out.println("joining reader threads");
133:                    }
134:
135:                    stdout_reader.join();
136:                    stderr_reader.join();
137:
138:                    // Get stdout and stderr from other threads.
139:
140:                    int numBytes;
141:                    numBytes = stdout_reader.appendBytes(sbuf);
142:                    if (debug) {
143:                        System.out.println("appended " + numBytes
144:                                + " bytes from stdout stream");
145:                    }
146:                    numBytes = stderr_reader.appendBytes(sbuf);
147:                    if (debug) {
148:                        System.out.println("appended " + numBytes
149:                                + " bytes from stderr stream");
150:                    }
151:
152:                    errorBytes = stderr_reader.getInBytes();
153:
154:                    // Check for the special case where there is no error
155:                    // data but the process returns an error result
156:
157:                    if ((errorBytes == 0) && (exit != 0)) {
158:                        sbuf.append("child process exited abnormally");
159:                    }
160:
161:                    // If the last character of the result buffer is a newline, then
162:                    // remove the newline character (the newline would just confuse
163:                    // things).  Finally, we set pass the result to the interpreter.
164:
165:                    int length = sbuf.length();
166:                    if (!keepNewline && (length > 0)
167:                            && (sbuf.charAt(length - 1) == '\n')) {
168:                        sbuf.setLength(length - 1);
169:                    }
170:
171:                    // Tcl supports lots of child status conditions.
172:                    // Unfortunately, we can only find the child's
173:                    // exit status using the Java API
174:
175:                    if (exit != 0) {
176:                        TclObject childstatus = TclList.newInstance();
177:                        TclList.append(interp, childstatus, TclString
178:                                .newInstance("CHILDSTATUS"));
179:
180:                        // We don't know how to find the child's pid
181:                        TclList.append(interp, childstatus, TclString
182:                                .newInstance("?PID?"));
183:
184:                        TclList.append(interp, childstatus, TclInteger
185:                                .newInstance(exit));
186:
187:                        interp.setErrorCode(childstatus);
188:                    }
189:
190:                    // when the subprocess writes to its stderr stream or returns
191:                    // a non zero result we generate an error
192:
193:                    if ((exit != 0) || (errorBytes != 0)) {
194:                        throw new TclException(interp, sbuf.toString());
195:                    }
196:
197:                    // otherwise things went well so set the result
198:
199:                    interp.setResult(sbuf.toString());
200:                } catch (IOException e) {
201:                    // if exec fails we end up catching the exception here
202:
203:                    throw new TclException(interp, "couldn't execute \""
204:                            + argv[firstWord].toString()
205:                            + "\": no such file or directory");
206:
207:                } catch (InterruptedException e) {
208:                    // Do Nothing...
209:                }
210:            }
211:
212:            /*
213:             *----------------------------------------------------------------------
214:             *
215:             * readStreamIntoBuffer --
216:             *
217:             *	This utility function will read the contents of an InputStream
218:             *	into a StringBuffer. When done it returns the number of bytes
219:             *	read from the InputStream. The assumption is an unbuffered stream
220:             *
221:             * Results:
222:             *	Returns the number of bytes read from the stream to the buffer
223:             *
224:             * Side effects:
225:             *	Data is read from the InputStream.
226:             *
227:             *----------------------------------------------------------------------
228:             */
229:
230:            static int readStreamIntoBuffer(InputStream in, StringBuffer sbuf) {
231:                int numRead = 0;
232:                BufferedReader br = new BufferedReader(
233:                        new InputStreamReader(in));
234:
235:                try {
236:                    String line = br.readLine();
237:
238:                    while (line != null) {
239:                        sbuf.append(line);
240:                        numRead += line.length();
241:                        sbuf.append('\n');
242:                        numRead++;
243:                        line = br.readLine();
244:                    }
245:                } catch (IOException e) {
246:                    // do nothing just return numRead
247:                    if (debug) {
248:                        System.out.println("IOException during stream read()");
249:                        e.printStackTrace(System.out);
250:                    }
251:                } finally {
252:                    try {
253:                        br.close();
254:                    } catch (IOException e) {
255:                        if (debug) {
256:                            System.out
257:                                    .println("IOException during stream close()");
258:                            e.printStackTrace(System.out);
259:                        }
260:                    }
261:                }
262:
263:                return numRead;
264:            }
265:
266:            /*
267:             *----------------------------------------------------------------------
268:             *
269:             * execCmd --
270:             *
271:             *	This procedure is invoked to process the "exec" call assuming the
272:             *	Runtime.exec( String[] cmdArr, String[] envArr, File currDir )
273:             *      API exists (introduced in JDK 1.3).
274:             *
275:             * Results:
276:             *	Returns the new process.
277:             *
278:             * Side effects:
279:             *	See the user documentation.
280:             *
281:             *----------------------------------------------------------------------
282:             */
283:
284:            private Process execCmd(Interp interp, TclObject argv[], int first,
285:                    int last) throws IOException {
286:                String[] strv = new String[last - first];
287:
288:                for (int i = first, j = 0; i < last; j++, i++) {
289:                    strv[j] = argv[i].toString();
290:                }
291:
292:                return Runtime.getRuntime().exec(strv, null,
293:                        interp.getWorkingDir());
294:            }
295:
296:        } // end ExecCmd
297:
298:        /*
299:         *----------------------------------------------------------------------
300:         *
301:         * ExecInputStreamReader --
302:         *
303:         *	Read data from an input stream into a StringBuffer.
304:         *	This code is executed in its own thread since some
305:         *	JDK implementation would deadlock when reading
306:         *	from a stream after waitFor is invoked.
307:         *----------------------------------------------------------------------
308:         */
309:
310:        class ExecInputStreamReader extends Thread {
311:            InputStream in;
312:            StringBuffer sb;
313:            int inBytes;
314:
315:            ExecInputStreamReader(InputStream in) {
316:                this .in = in;
317:                this .sb = new StringBuffer();
318:                inBytes = 0;
319:            }
320:
321:            public void run() {
322:                inBytes = ExecCmd.readStreamIntoBuffer(in, sb);
323:            }
324:
325:            int appendBytes(StringBuffer dest) {
326:                int bytes = sb.length();
327:                dest.append(sb.toString());
328:                return bytes;
329:            }
330:
331:            int getInBytes() {
332:                return inBytes;
333:            }
334:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.