File: sh.c

package info (click to toggle)
scilab 2.6-4
  • links: PTS
  • area: non-free
  • in suites: woody
  • size: 54,632 kB
  • ctags: 40,267
  • sloc: ansic: 267,851; fortran: 166,549; sh: 10,005; makefile: 4,119; tcl: 1,070; cpp: 233; csh: 143; asm: 135; perl: 130; java: 39
file content (183 lines) | stat: -rw-r--r-- 4,564 bytes parent folder | download
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183


/* Copyright (C) 1998 Chancelier Jean-Philippe */
#include <stdio.h>
#include <windows.h>
#include <string.h>

HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup, hChildStdoutRd,
  hChildStdoutWr, hInputFile, hSaveStdin, hSaveStdout;

BOOL CreateChildProcess (VOID);
VOID WriteToPipe (VOID);
VOID UsePipe (VOID);
VOID ReadFromPipe (VOID);
VOID ErrMsg (LPTSTR, BOOL);

int 
InitSh ()
{
  SECURITY_ATTRIBUTES saAttr;
  BOOL fSuccess;

  /* Set the bInheritHandle flag so pipe handles are inherited. */

  saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
  saAttr.bInheritHandle = TRUE;
  saAttr.lpSecurityDescriptor = NULL;

  /* 
   * The steps for redirecting child's STDOUT: 
   *     1.  Save current STDOUT, to be restored later. 
   *     2.  Create anonymous pipe to be STDOUT for child. 
   *     3.  Set STDOUT of parent to be write handle of pipe, so 
   *         it is inherited by child. 
   */

  /* Save the handle to the current STDOUT. */

  hSaveStdout = GetStdHandle (STD_OUTPUT_HANDLE);

  /* Create a pipe for the child's STDOUT. */

  if (!CreatePipe (&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
    {
      sciprint ("Stdout pipe creation failed\n");
      return (1);
    }

  /* Set a write handle to the pipe to be STDOUT. */

  if (!SetStdHandle (STD_OUTPUT_HANDLE, hChildStdoutWr))
    {
      sciprint ("Redirecting STDOUT failed\r\n");
      return (1);
    }

  /* 
   * The steps for redirecting child's STDIN: 
   *     1.  Save current STDIN, to be restored later. 
   *     2.  Create anonymous pipe to be STDIN for child. 
   *     3.  Set STDIN of parent to be read handle of pipe, so 
   *         it is inherited by child. 
   *     4.  Create a noninheritable duplicate of write handle, 
   *         and close the inheritable write handle. 
   */

  /* Save the handle to the current STDIN. */

  hSaveStdin = GetStdHandle (STD_INPUT_HANDLE);

  /* Create a pipe for the child's STDIN. */

  if (!CreatePipe (&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
    {
      sciprint ("Stdin pipe creation failed\r\n");;
      return (1);
    }

  /* Set a read handle to the pipe to be STDIN. */

  if (!SetStdHandle (STD_INPUT_HANDLE, hChildStdinRd))
    {
      sciprint ("Redirecting Stdin failed\r\n");
      return (1);
    }
  /* Duplicate the write handle to the pipe so it is not inherited. */

  fSuccess = DuplicateHandle (GetCurrentProcess (), hChildStdinWr,
			      GetCurrentProcess (), &hChildStdinWrDup, 0,
			      FALSE,	/* not inherited */
			      DUPLICATE_SAME_ACCESS);
  if (!fSuccess)
    {
      sciprint ("DuplicateHandle failed\r\n");
      return (1);
    }

  CloseHandle (hChildStdinWr);

  /* Now create the child process. */

  if (!CreateChildProcess ())
    {
      sciprint ("Create process failed\r\n");
    }

  /* After process creation, restore the saved STDIN and STDOUT. */

  if (!SetStdHandle (STD_INPUT_HANDLE, hSaveStdin))
    {
      sciprint ("Re-redirecting Stdin failed\r\n");
      return (1);
    }

  if (!SetStdHandle (STD_OUTPUT_HANDLE, hSaveStdout))
    {
      sciprint ("Re-redirecting Stdout failed\r\n");
      return (1);
    }
  return (0);
}

BOOL 
CreateChildProcess ()
{
  PROCESS_INFORMATION piProcInfo;
  STARTUPINFO siStartInfo;

  /* Set up members of STARTUPINFO structure. */

  siStartInfo.cb = sizeof (STARTUPINFO);
  siStartInfo.lpReserved = NULL;
  siStartInfo.lpReserved2 = NULL;
  siStartInfo.cbReserved2 = 0;
  siStartInfo.lpDesktop = NULL;
  siStartInfo.dwFlags = 0;

  /* Create the child process. */

  return CreateProcess (NULL,
			"child",	/* command line                       */
			NULL,	/* process security attributes        */
			NULL,	/* primary thread security attributes */
			TRUE,	/* handles are inherited              */
			0,	/* creation flags                     */
			NULL,	/* use parent's environment           */
			NULL,	/* use parent's current directory     */
			&siStartInfo,	/* STARTUPINFO pointer                */
			&piProcInfo);	/* receives PROCESS_INFORMATION       */
}

void 
SendToSh (char *str)
{
  DWORD dwWritten;
  WriteFile (hChildStdinWrDup, str, strlen (str), &dwWritten, NULL);
}

#define BUFSIZE 256

void 
ReadAnswer (void)
{
  int count = 0;
  DWORD dwRead;
  CHAR chBuf[BUFSIZE], c[1];
  for (;;)
    {
      ReadFile (hChildStdoutRd, c, 1, &dwRead, NULL);
      if (dwRead == 0)
	return;
      chBuf[count] = c[0];
      count++;
      if (strncmp (chBuf, "bash", 4) == 0)
	return;
      if (c[0] == '\n' || count == BUFSIZE - 1)
	{
	  chBuf[count] = '\0';
	  sciprint (chBuf);
	  count = 0;
	}
    }
}