Mercurial > 510Connectbot
annotate src/ch/ethz/ssh2/SCPInputStream.java @ 399:aeb8c2e6d83a
add queue to buffer monitor socket writes to prevent blocking on socket output stream write
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Wed, 15 Oct 2014 18:03:27 -0700 |
parents | 071eccdff8ea |
children |
rev | line source |
---|---|
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
1 /* |
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
2 * Copyright (c) 2011 David Kocher. All rights reserved. |
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
3 * Please refer to the LICENSE.txt for licensing details. |
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
4 */ |
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
5 package ch.ethz.ssh2; |
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
6 |
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
7 import java.io.BufferedInputStream; |
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
8 import java.io.BufferedOutputStream; |
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
9 import java.io.IOException; |
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
10 import java.io.OutputStream; |
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
11 |
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
12 /** |
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
13 * @version $Id: SCPInputStream.java 151 2014-04-28 10:03:39Z dkocher@sudo.ch $ |
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
14 */ |
307 | 15 public class SCPInputStream extends BufferedInputStream { |
16 private Session session; | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
17 |
307 | 18 /** |
19 * Bytes remaining to be read from the stream | |
20 */ | |
21 private long remaining; | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
22 |
307 | 23 public SCPInputStream(SCPClient client, Session session) throws IOException { |
24 super(session.getStdout()); | |
25 this.session = session; | |
26 OutputStream os = new BufferedOutputStream(session.getStdin(), 512); | |
27 os.write(0x0); | |
28 os.flush(); | |
29 final SCPClient.LenNamePair lnp; | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
30 |
307 | 31 while (true) { |
32 int c = session.getStdout().read(); | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
33 |
307 | 34 if (c < 0) { |
35 throw new IOException("Remote scp terminated unexpectedly."); | |
36 } | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
37 |
307 | 38 String line = client.receiveLine(session.getStdout()); |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
39 |
307 | 40 if (c == 'T') { |
41 /* Ignore modification times */ | |
42 continue; | |
43 } | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
44 |
307 | 45 if ((c == 1) || (c == 2)) { |
46 throw new IOException("Remote SCP error: " + line); | |
47 } | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
48 |
307 | 49 if (c == 'C') { |
50 lnp = client.parseCLine(line); | |
51 break; | |
52 } | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
53 |
307 | 54 throw new IOException("Remote SCP error: " + ((char) c) + line); |
55 } | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
56 |
307 | 57 os.write(0x0); |
58 os.flush(); | |
59 this.remaining = lnp.length; | |
60 } | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
61 |
307 | 62 @Override |
63 public int read() throws IOException { | |
64 if (!(remaining > 0)) { | |
65 return -1; | |
66 } | |
67 | |
68 int b = super.read(); | |
69 | |
70 if (b < 0) { | |
71 throw new IOException("Remote scp terminated connection unexpectedly"); | |
72 } | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
73 |
307 | 74 remaining -= 1; |
75 return b; | |
76 } | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
77 |
307 | 78 @Override |
79 public int read(byte b[], int off, int len) throws IOException { | |
80 if (!(remaining > 0)) { | |
81 return -1; | |
82 } | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
83 |
307 | 84 int trans = (int) remaining; |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
85 |
307 | 86 if (remaining > len) { |
87 trans = len; | |
88 } | |
89 | |
90 int read = super.read(b, off, trans); | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
91 |
307 | 92 if (read < 0) { |
93 throw new IOException("Remote scp terminated connection unexpectedly"); | |
94 } | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
95 |
307 | 96 remaining -= read; |
97 return read; | |
98 } | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
99 |
307 | 100 @Override |
101 public void close() throws IOException { | |
102 try { | |
103 session.getStdin().write(0x0); | |
104 session.getStdin().flush(); | |
105 } | |
106 finally { | |
107 if (session != null) { | |
108 session.close(); | |
109 } | |
110 } | |
111 } | |
273
91a31873c42a
start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff
changeset
|
112 } |