<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -23,6 +23,10 @@ using namespace std;
 
 extern int errno;
 extern char** environ;
+bool interactive = false;
+int waitingpid = 0;
+bool color_output = false;
+string msg_head = &quot;[ZRSh] &quot;;
 
 #ifdef DEBUG
 /**
@@ -31,15 +35,12 @@ extern char** environ;
  */
 void debug(string msg)
 {
-	cerr &lt;&lt; &quot;[ZRSh (&quot; &lt;&lt; getpid() &lt;&lt; &quot;)] &quot; &lt;&lt; msg &lt;&lt; endl;
+	cerr &lt;&lt; msg_head &lt;&lt; &quot;(&quot; &lt;&lt; getpid() &lt;&lt; &quot;)&quot; &lt;&lt; msg &lt;&lt; endl;
 }
 #else
 void debug(string msg) {}
 #endif
 
-bool interactive = false;
-int waitingpid = 0;
-
 /**
  * This method gives you string trimmed the extra whitespaces in the begin or end.
  * @param str String to be trimmed
@@ -117,7 +118,7 @@ void execute(ZRCommandParserResultPart r)
 	// MYPATH is not found, use PATH instead.
 	if (!searchPath)
 	{
-		cerr &lt;&lt; &quot;[ZRSh] MYPATH is not found, fallback to PATH&quot; &lt;&lt; endl;
+		cerr &lt;&lt; msg_head &lt;&lt; &quot;MYPATH is not found, fallback to PATH&quot; &lt;&lt; endl;
 		searchPath = getenv(&quot;PATH&quot;);
 	}
 	
@@ -154,7 +155,7 @@ void execute(ZRCommandParserResultPart r)
 		fp = fopen(r.redirIn.c_str(), &quot;r&quot;);
 		fd = fileno(fp);
 		if (dup2(fd, STDIN_FILENO) == -1)
-			cerr &lt;&lt; &quot;[ZRSh] Unable to redirect STDIN from &quot; &lt;&lt; r.redirIn &lt;&lt; endl;
+			cerr &lt;&lt; msg_head &lt;&lt; &quot;Unable to redirect STDIN from &quot; &lt;&lt; r.redirIn &lt;&lt; endl;
 	}
 
 	if (r.redirOut != &quot;&quot;)
@@ -162,7 +163,7 @@ void execute(ZRCommandParserResultPart r)
 		fp = fopen(r.redirOut.c_str(), &quot;w&quot;);
 		fd = fileno(fp);
 		if (dup2(fd, STDOUT_FILENO) == -1)
-			cerr &lt;&lt; &quot;[ZRSh] Unable to redirect STDOUT to &quot; &lt;&lt; r.redirOut &lt;&lt; endl;
+			cerr &lt;&lt; msg_head &lt;&lt; &quot;Unable to redirect STDOUT to &quot; &lt;&lt; r.redirOut &lt;&lt; endl;
 	}
 
 	if (r.redirAppend != &quot;&quot;)
@@ -170,13 +171,13 @@ void execute(ZRCommandParserResultPart r)
 		fp = fopen(r.redirAppend.c_str(), &quot;a&quot;);
 		fd = fileno(fp);
 		if (dup2(fd, STDOUT_FILENO) == -1)
-			cerr &lt;&lt; &quot;[ZRSh] Unable to redirect and append STDOUT to &quot; &lt;&lt; r.redirAppend &lt;&lt; endl;
+			cerr &lt;&lt; msg_head &lt;&lt; &quot;Unable to redirect and append STDOUT to &quot; &lt;&lt; r.redirAppend &lt;&lt; endl;
 	}
 	
 	execv(arg_list[0], arg_list);
 
 	// Code below only runs when exec is failed.
-	cout &lt;&lt; &quot;[ZRSh] Unable to execute command. (code: &quot; &lt;&lt; errno &lt;&lt; &quot;)&quot; &lt;&lt; endl;
+	cout &lt;&lt; msg_head &lt;&lt; &quot;Unable to execute command. (code: &quot; &lt;&lt; errno &lt;&lt; &quot;)&quot; &lt;&lt; endl;
 	exit(-1);
 
 	for(i = 0;i &lt; r.arguments.size();i++)
@@ -205,7 +206,7 @@ void spawn(ZRCommandParserResultPart r)
 		}
 	}
 	else
-		cout &lt;&lt; &quot;[ZRSh] Sorry, fork failed!&quot; &lt;&lt; endl;
+		cout &lt;&lt; msg_head &lt;&lt; &quot;Sorry, fork failed!&quot; &lt;&lt; endl;
 	
 	return;
 }
@@ -220,7 +221,7 @@ int spawn_for_pipe(vector&lt;ZRCommandParserResultPart&gt;::iterator begin, vector&lt;ZRC
 {
 	int fds[2];
 	if (pipe(fds) == -1)
-		cout &lt;&lt; &quot;[ZRSh] Unable to create pipe (code: &quot; &lt;&lt; errno &lt;&lt; &quot;)&quot; &lt;&lt; endl;
+		cout &lt;&lt; msg_head &lt;&lt; &quot;Unable to create pipe (code: &quot; &lt;&lt; errno &lt;&lt; &quot;)&quot; &lt;&lt; endl;
 	
 	vector&lt;ZRCommandParserResultPart&gt;::iterator nxtItr = begin + 1;
 	
@@ -230,27 +231,27 @@ int spawn_for_pipe(vector&lt;ZRCommandParserResultPart&gt;::iterator begin, vector&lt;ZRC
 		if (begin-&gt;pipe_with_next)
 		{
 			if (dup2(fds[1], STDOUT_FILENO) == -1)
-				cerr &lt;&lt; &quot;[ZRSh] dup2 failed. (STDOUT)&quot; &lt;&lt; endl;
+				cerr &lt;&lt; msg_head &lt;&lt; &quot;dup2 failed. (STDOUT)&quot; &lt;&lt; endl;
 		}
 
 		if (close(fds[0]) == -1)
-			cerr &lt;&lt; &quot;[ZRSh] close failed. (PIPE_READ)&quot; &lt;&lt; endl;
+			cerr &lt;&lt; msg_head &lt;&lt; &quot;close failed. (PIPE_READ)&quot; &lt;&lt; endl;
 
 		if (close(fds[1]) == -1)
-			cerr &lt;&lt; &quot;[ZRSh] close failed. (PIPE_WRITE)&quot; &lt;&lt; endl;
+			cerr &lt;&lt; msg_head &lt;&lt; &quot;close failed. (PIPE_WRITE)&quot; &lt;&lt; endl;
 			
 		execute(*begin);
 	}
 	else if (pid &gt; 0)
 	{
 		if (dup2(fds[0], STDIN_FILENO) == -1)
-			cerr &lt;&lt; &quot;[ZRSh] dup2 failed. (STDIN)&quot; &lt;&lt; endl;
+			cerr &lt;&lt; msg_head &lt;&lt; &quot;dup2 failed. (STDIN)&quot; &lt;&lt; endl;
 
 		if (close(fds[0]) == -1)
-			cerr &lt;&lt; &quot;[ZRSh] close failed. (PIPE_READ)&quot; &lt;&lt; endl;
+			cerr &lt;&lt; msg_head &lt;&lt; &quot;close failed. (PIPE_READ)&quot; &lt;&lt; endl;
 
 		if (close(fds[1]) == -1)
-			cerr &lt;&lt; &quot;[ZRSh] close failed. (PIPE_WRITE)&quot; &lt;&lt; endl;
+			cerr &lt;&lt; msg_head &lt;&lt; &quot;close failed. (PIPE_WRITE)&quot; &lt;&lt; endl;
 				
 		if (nxtItr == end)
 		{
@@ -263,7 +264,7 @@ int spawn_for_pipe(vector&lt;ZRCommandParserResultPart&gt;::iterator begin, vector&lt;ZRC
 			return spawn_for_pipe(nxtItr, end);
 	}
 	else
-		cerr &lt;&lt; &quot;[ZRSh] Sorry, fork failed!&quot; &lt;&lt; endl;
+		cerr &lt;&lt; msg_head &lt;&lt; &quot;Sorry, fork failed!&quot; &lt;&lt; endl;
 	
 	return -1;
 }
@@ -276,22 +277,36 @@ void sigint_handler(int sig)
 {
 	if (!interactive)
 	{
-		cout &lt;&lt; endl &lt;&lt; &quot;[ZRSh] Sending SIGINT to Kill the foreground process...&quot; &lt;&lt; endl;
+		cout &lt;&lt; endl &lt;&lt; msg_head &lt;&lt; &quot;Sending SIGINT to Kill the foreground process...&quot; &lt;&lt; endl;
 		kill(waitingpid, SIGINT);
 		cout &lt;&lt; endl;
 	}
 	else
 	{
-		cout &lt;&lt; endl &lt;&lt; &quot;[ZRSh] Received SIGINT, bye!&quot; &lt;&lt; endl;
+		cout &lt;&lt; endl &lt;&lt; msg_head &lt;&lt; &quot;Received SIGINT, bye!&quot; &lt;&lt; endl;
 		exit(0);
 	}
 }
 
 int main()
 {
-	cout &lt;&lt; &quot;Welcome to ZeroShell(ZRSh) 1.0&quot; &lt;&lt; endl;
-	cout &lt;&lt; &quot;Copyright by Zero Cho 2009. Licensed under MIT license.&quot; &lt;&lt; endl;
-	cout &lt;&lt; &quot;Initializing in progress...&quot; &lt;&lt; endl;
+	// Check if the STDOUT is a terminal and support color output
+	if (isatty(STDOUT_FILENO) &amp;&amp; strcmp(getenv(&quot;TERM&quot;), &quot;dumb&quot;))
+		color_output = true;
+	
+	if (!color_output)
+	{
+		cout &lt;&lt; &quot;Welcome to ZeroShell(ZRSh) 1.0&quot; &lt;&lt; endl;
+		cout &lt;&lt; &quot;Copyright by Zero Cho 2009. Licensed under MIT license.&quot; &lt;&lt; endl;
+		cout &lt;&lt; &quot;Initializing in progress...&quot; &lt;&lt; endl;
+	}
+	else
+	{
+		cout &lt;&lt; &quot;\033[1;37mWelcome to \033[1;31mZeroShell\033[m(\033[1;31mZRSh\033[m) 1.0\033[m&quot; &lt;&lt; endl;
+		cout &lt;&lt; &quot;Copyright by Zero Cho 2009. Licensed under MIT license.&quot; &lt;&lt; endl;
+		cout &lt;&lt; &quot;\033[1;33mInitializing in progress...\033[m&quot; &lt;&lt; endl;
+		msg_head = &quot;\033[1;31m[ZRSH]\033[m &quot;;
+	}
 	// Initialize the readline library and generate prompt
 	vector&lt;string&gt; history;
 	string command;
@@ -305,7 +320,7 @@ int main()
 	// Install SIGINT catcher
 	signal(SIGINT, sigint_handler);
 	
-	cout &lt;&lt; &quot;Done, dropping you to shell.&quot; &lt;&lt; endl &lt;&lt; endl;
+	cout &lt;&lt; &quot;\033[1;32mDone, dropping you to shell.\033[m&quot; &lt;&lt; endl &lt;&lt; endl;
 	
 	// Command input routine
 	while(true)
@@ -317,7 +332,7 @@ int main()
 		getcwd(path_c, size);
 		if (!path_c)
 		{
-			cout &lt;&lt; &quot;[ZRSh] ERROR: Unable to construct prompt. (code: &quot; &lt;&lt; errno &lt;&lt; &quot;)&quot; &lt;&lt; endl;
+			cout &lt;&lt; msg_head &lt;&lt; &quot;ERROR: Unable to construct prompt. (code: &quot; &lt;&lt; errno &lt;&lt; &quot;)&quot; &lt;&lt; endl;
 			exit(-1);
 		}
 		
@@ -328,7 +343,10 @@ int main()
 		int pos = path.find(home);
 		if (pos != string::npos)
 			path = &quot;~&quot; + path.substr(home.length(), path.length() - home.length());
-		oss &lt;&lt; getenv(&quot;USER&quot;) &lt;&lt; &quot;@&quot; &lt;&lt; hostname &lt;&lt; &quot; &quot; &lt;&lt; path &lt;&lt; &quot;&gt; &quot;;
+		if (color_output)
+			oss &lt;&lt; &quot;[\033[33m&quot; &lt;&lt; getenv(&quot;USER&quot;) &lt;&lt; &quot;\033[m@\033[32m&quot; &lt;&lt; hostname &lt;&lt; &quot;\033[m] &quot; &lt;&lt; path &lt;&lt; &quot;&gt; &quot;;
+		else
+			oss &lt;&lt; getenv(&quot;USER&quot;) &lt;&lt; &quot;@&quot; &lt;&lt; hostname &lt;&lt; &quot; &quot; &lt;&lt; path &lt;&lt; &quot;&gt; &quot;;
 		
 		// Read input command
 		input = readline(oss.str().c_str());
@@ -374,8 +392,8 @@ int main()
 				setenv(r.parts[0].arguments[0].c_str(), r.parts[0].arguments[1].c_str(), true);
 			else
 			{
-				cout &lt;&lt; &quot;setenv requires 1 or 2 arguments, you give me &quot; &lt;&lt; r.parts[0].arguments.size() &lt;&lt; &quot; arguments.&quot; &lt;&lt; endl;
-				cout &lt;&lt; &quot;Please check \&quot;help\&quot; command.&quot; &lt;&lt; endl;
+				cout &lt;&lt; msg_head &lt;&lt; &quot;setenv requires 1 or 2 arguments, you give me &quot; &lt;&lt; r.parts[0].arguments.size() &lt;&lt; &quot; arguments.&quot; &lt;&lt; endl;
+				cout &lt;&lt; msg_head &lt;&lt; &quot;Please check \&quot;help\&quot; command.&quot; &lt;&lt; endl;
 			}
 		}
 		else if (r.parts[0].command == &quot;listenv&quot;)</diff>
      <filename>zrsh.cpp</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>7734f56dca142273814c6d69017b8c39150f5aa4</id>
    </parent>
  </parents>
  <author>
    <name>Chien-An Cho (Zero Cho)</name>
    <email>itszero@gmail.com</email>
  </author>
  <url>http://github.com/itszero/ZeroShell/commit/cd629b21d273a2579bb04a4a630d4d0d37aafadc</url>
  <id>cd629b21d273a2579bb04a4a630d4d0d37aafadc</id>
  <committed-date>2009-04-14T10:58:26-07:00</committed-date>
  <authored-date>2009-04-14T10:58:26-07:00</authored-date>
  <message>Added color terminal detection, I just love colors.</message>
  <tree>fbf5f281f5ddd3dda3af3ebcf98930494e606d10</tree>
  <committer>
    <name>Chien-An Cho (Zero Cho)</name>
    <email>itszero@gmail.com</email>
  </committer>
</commit>
