Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ExecConnection.cs « Clovershell - github.com/ClusterM/hakchi2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 2e6828129e08da6b178082fc621ac1c93e2b4775 (plain)
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
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

namespace com.clusterrr.clovershell
{
    internal class ExecConnection : IDisposable
    {
        internal readonly ClovershellConnection connection;
        internal readonly string command;
        internal Stream stdin;
        internal Int32 stdinPipeSize;
        internal Int32 stdinQueue;
        internal Stream stdout;
        internal Stream stderr;
        internal int id;
        internal bool finished;
        internal int result;
        internal bool stdinFinished;
        internal bool stdoutFinished;
        internal bool stderrFinished;
        internal Thread stdinThread;
        internal DateTime LastDataTime;

        public ExecConnection(ClovershellConnection connection, string command, Stream stdin, Stream stdout, Stream stderr)
        {
            this.connection = connection;
            this.command = command;
            id = -1;
            stdinPipeSize = 0;
            stdinQueue = 0;
            this.stdin = stdin;
            this.stdout = stdout;
            this.stderr = stderr;
            finished = false;
            stdinFinished = false;
            stdoutFinished = false;
            stderrFinished = false;
            LastDataTime = DateTime.Now;
        }

        public void stdinLoop()
        {
            try
            {
                if (stdin == null) return;
                if (stdin.CanSeek)
                    stdin.Seek(0, SeekOrigin.Begin);
                var buffer = new byte[8 * 1024];
                int l;
                while (connection.IsOnline)
                {
                    l = stdin.Read(buffer, 0, buffer.Length);
                    if (l > 0)
                        connection.writeUsb(ClovershellConnection.ClovershellCommand.CMD_EXEC_STDIN, (byte)id, buffer, 0, l);
                    else
                        break;
                    LastDataTime = DateTime.Now;
                    if (stdinQueue > 32 * 1024 && connection.IsOnline)
                    {
                        Debug.WriteLine(string.Format("queue: {0} / {1}, {2}MB / {3}MB ({4}%)",
                            stdinQueue, stdinPipeSize, stdin.Position / 1024 / 1024, stdin.Length / 1024 / 1024, 100 * stdin.Position / stdin.Length));
                        while (stdinQueue > 16 * 1024)
                        {
                            Thread.Sleep(50);
                            connection.writeUsb(ClovershellConnection.ClovershellCommand.CMD_EXEC_STDIN_FLOW_STAT_REQ, (byte)id);
                        }
                    }
                }
                connection.writeUsb(ClovershellConnection.ClovershellCommand.CMD_EXEC_STDIN, (byte)id); // eof
                if (stdinQueue > 0 && connection.IsOnline)
                {
                    Thread.Sleep(50);
                    connection.writeUsb(ClovershellConnection.ClovershellCommand.CMD_EXEC_STDIN_FLOW_STAT_REQ, (byte)id);
                }
                stdinFinished = true;
            }
            catch (ThreadAbortException) { }
            catch (ClovershellException ex)
            {
                Debug.WriteLine("stdin error: " + ex.Message + ex.StackTrace);
            }
            finally
            {
                stdinThread = null;
            }
        }

        public void Dispose()
        {
            if (stdinThread != null)
                stdinThread.Abort();            
        }
    }

}