forked from Drive-for-Java/MyCMD
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTimeoutCommand.java
More file actions
149 lines (135 loc) · 5.34 KB
/
Copy pathTimeoutCommand.java
File metadata and controls
149 lines (135 loc) · 5.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package com.mycmd.commands;
import com.mycmd.Command;
import com.mycmd.ShellContext;
import java.io.IOException;
public class TimeoutCommand implements Command {
@Override
public void execute(String[] args, ShellContext context) {
int seconds = -1;
boolean hasSecondsArg = false;
boolean hasSlashT = false;
boolean noBreak = false;
for (int i = 0; i < args.length; i++) {
if (args[i].equalsIgnoreCase("/t")
&& i + 1 < args.length
&& args[i + 1].matches("[+-]?\\d+")) {
if (hasSlashT) {
System.out.println(
"Error: Invalid syntax. '/t' option is not allowed more than '1' time(s).");
return;
}
seconds = Integer.parseInt(args[i + 1]);
i++;
hasSecondsArg = true;
hasSlashT = true;
} else if (args[i].equalsIgnoreCase("/nobreak")) {
if (noBreak) {
System.out.println(
"Error: Invalid syntax. '/nobreak' option is not allowed more than '1' time(s).");
return;
}
noBreak = true;
} else if (args[i].matches("[+-]?\\d+")) {
if (hasSecondsArg) {
System.out.println(
"Error: Invalid syntax. Default option is not allowed more than '1' time(s).");
return;
}
seconds = Integer.parseInt(args[i]);
hasSecondsArg = true;
} else if (args[i].equalsIgnoreCase("/t")) {
System.out.println("Error: Invalid syntax. Value expected for '/t'.");
return;
}
}
if (!hasSecondsArg) {
System.out.println("Error: Invalid syntax. Seconds value is required.");
return;
}
if (seconds < -1 || seconds > 99999) {
System.out.println(
"Error: Invalid value for timeout specified. Valid range is 0-99999 seconds.");
return;
}
if (seconds == -1) {
System.out.println();
PauseCommand pauseCmd = new PauseCommand();
pauseCmd.execute(new String[0], context);
return;
}
AtomicBoolean interrupted = new AtomicBoolean(false);
Thread inputThread = null;
if (!noBreak) {
inputThread =
new Thread(
() -> {
try {
int r;
// Read until a newline is encountered so we only exit on Enter
while ((r = System.in.read()) != -1) {
if (r == '\n') {
interrupted.set(true);
break;
}
}
} catch (IOException e) {
// Ignore: if System.in is closed or an I/O error occurs we
// cannot reliably wait for Enter; treat as no-interrupt.
}
});
inputThread.setDaemon(true);
inputThread.start();
}
System.out.println();
for (; seconds > 0; seconds--) {
if (!noBreak && interrupted.get()) {
System.out.println("\r");
System.out.println();
if (inputThread != null && inputThread.isAlive()) {
inputThread.interrupt();
}
return;
}
System.out.print(
"\rWaiting for "
+ seconds
+ " seconds, press "
+ (noBreak ? "CTRL+C to quit ..." : "enter key to continue ..."));
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
if (noBreak) {
continue;
}
System.out.println();
Thread.currentThread().interrupt();
break;
}
}
try {
// Drain any remaining bytes so subsequent commands don't immediately see
// leftover input. This is a best-effort drain; System.in.available() may
// not be supported on all streams, but for typical console streams it helps.
while (System.in.available() > 0) {
System.in.read();
}
} catch (IOException e) {
// Ignore: if we can't drain the stream it's non-fatal; any leftover input
// will be handled by the next read and is acceptable.
}
System.out.println("\r");
System.out.println();
}
@Override
public String description() {
return "Sets a timeout for command execution.";
}
@Override
public String usage() {
return "timeout <seconds>\n"
+ "timeout /t <seconds>\n"
+ "timeout /t <seconds> /nobreak\n"
+ "timeout /t -1";
}
}