posix 0.0.0 → 0.0.1
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.
- data/ext/posix/extconf.rb +4 -0
- data/ext/posix/posix.c +146 -0
- data/lib/posix/sigset.rb +22 -0
- data/lib/posix.rb +5 -0
- data/posix.gemspec +2 -2
- metadata +7 -2
data/ext/posix/posix.c
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <ruby/st.h>
|
3
|
+
#include <errno.h>
|
4
|
+
#include <signal.h>
|
5
|
+
#include <unistd.h>
|
6
|
+
|
7
|
+
void Init_posix(void);
|
8
|
+
static VALUE rb_hash_keys(VALUE hash);
|
9
|
+
|
10
|
+
#define RB_POSIX_SIG_BLOCK SIG_BLOCK
|
11
|
+
#define RB_POSIX_SIG_UNBLOCK SIG_UNBLOCK
|
12
|
+
#define RB_POSIX_SIG_SETMASK SIG_SETMASK
|
13
|
+
|
14
|
+
int rb_Sigset2sigset_t(VALUE rb_Sigset, sigset_t *sigset) {
|
15
|
+
int i;
|
16
|
+
VALUE signals;
|
17
|
+
|
18
|
+
|
19
|
+
sigemptyset(sigset);
|
20
|
+
signals = rb_iv_get(rb_Sigset, "@signals");
|
21
|
+
|
22
|
+
for (i = 0; i < RARRAY_LEN(signals); i++) {
|
23
|
+
sigaddset(sigset, FIX2INT(RARRAY_PTR(signals)[i]));
|
24
|
+
}
|
25
|
+
return 0;
|
26
|
+
}
|
27
|
+
|
28
|
+
/* @see man 2 sigprocmask
|
29
|
+
*
|
30
|
+
* Doesn't accept a third argument, instead returns the new set
|
31
|
+
*/
|
32
|
+
|
33
|
+
VALUE posix_sigprocmask(VALUE self, VALUE _how, VALUE _set) {
|
34
|
+
int how;
|
35
|
+
sigset_t *set;
|
36
|
+
sigset_t *oset = NULL; // TODO, storage for returnvalue
|
37
|
+
|
38
|
+
how = FIX2INT(_how);
|
39
|
+
|
40
|
+
if (_set == Qnil) {
|
41
|
+
set = NULL;
|
42
|
+
} else {
|
43
|
+
set = malloc(sizeof(sigset_t));
|
44
|
+
rb_Sigset2sigset_t(_set, set);
|
45
|
+
}
|
46
|
+
|
47
|
+
sigemptyset(set);
|
48
|
+
sigaddset(set, SIGINT);
|
49
|
+
|
50
|
+
if (sigprocmask(how, set, oset) == 0) {
|
51
|
+
// TODO Construct a Sigset and return it so that we can interrogate it
|
52
|
+
|
53
|
+
if(set)
|
54
|
+
free(set);
|
55
|
+
return Qtrue;
|
56
|
+
} else {
|
57
|
+
if(set)
|
58
|
+
free(set);
|
59
|
+
rb_raise(rb_eException, "%s", strerror(errno));
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
/* Export an argv that does sane, reasonable things instead of doing weird
|
64
|
+
* shit.
|
65
|
+
*
|
66
|
+
* Return value is largely irrelevant
|
67
|
+
*/
|
68
|
+
VALUE posix_execve(VALUE self, VALUE _binary, VALUE _argv, VALUE _envp) {
|
69
|
+
/* Iterators */
|
70
|
+
int i;
|
71
|
+
VALUE akey, keys, envk;
|
72
|
+
|
73
|
+
/* Binary to load in the new process */
|
74
|
+
char* binary = StringValueCStr(_binary);
|
75
|
+
|
76
|
+
/* Construct our new process' argv. Onus is on
|
77
|
+
* the programmer to set ARGV[0] to something
|
78
|
+
* reasonable. */
|
79
|
+
char** argv = malloc(sizeof(char*)*RARRAY_LEN(_argv) + 1);
|
80
|
+
|
81
|
+
for (i = 0; i < RARRAY_LEN(_argv); i++) {
|
82
|
+
argv[i] = StringValuePtr(RARRAY_PTR(_argv)[i]);
|
83
|
+
argv[i+1] = NULL; /* Ensure that we're null terminated */
|
84
|
+
}
|
85
|
+
|
86
|
+
/* Construct our environment. Note that this totally ignores the precedent
|
87
|
+
* set by Process#spawn, Kernel#exec and fiends */
|
88
|
+
|
89
|
+
fprintf(stderr, "Allocatin' some memory\n");
|
90
|
+
char **envp = malloc(sizeof(char**)*RHASH(_envp)->ntbl->num_entries + 1);
|
91
|
+
fprintf(stderr, "Allocated some memory\n");
|
92
|
+
i = 0;
|
93
|
+
|
94
|
+
keys = rb_hash_keys(_envp);
|
95
|
+
for (i = 0; i < RARRAY_LEN(keys); i++) {
|
96
|
+
akey = RARRAY_PTR(keys)[i];
|
97
|
+
envk = rb_hash_aref(_envp, akey);
|
98
|
+
fprintf(stderr, "printin' some stringz");
|
99
|
+
asprintf(&envp[i], "%s=%s", StringValuePtr(akey), StringValuePtr(envk));
|
100
|
+
fprintf(stderr, "printed some stringz");
|
101
|
+
envp[i+1] = NULL; /* Ensure that we're null terminated */
|
102
|
+
}
|
103
|
+
fprintf(stderr,"%s", envp[0]);
|
104
|
+
|
105
|
+
binary = "/bin/bash";
|
106
|
+
char *__envp[] = { NULL };
|
107
|
+
char *__argv[] = { "/bin/bash", NULL };
|
108
|
+
execve(binary, argv, envp);
|
109
|
+
fprintf(stderr, "Error: %s", strerror(errno));
|
110
|
+
}
|
111
|
+
|
112
|
+
void Init_posix(void) {
|
113
|
+
/* Create ::Posix */
|
114
|
+
VALUE klass = rb_define_class("Posix", rb_cObject);
|
115
|
+
|
116
|
+
/* Define constants */
|
117
|
+
rb_define_const(klass, "SIG_BLOCK", INT2FIX(RB_POSIX_SIG_BLOCK));
|
118
|
+
rb_define_const(klass, "SIG_UNBLOCK", INT2FIX(RB_POSIX_SIG_UNBLOCK));
|
119
|
+
rb_define_const(klass, "SIG_SETMASK", INT2FIX(RB_POSIX_SIG_SETMASK));
|
120
|
+
|
121
|
+
/* Method binding */
|
122
|
+
rb_define_singleton_method(klass, "sigprocmask", posix_sigprocmask, 2);
|
123
|
+
rb_define_singleton_method(klass, "execve", posix_execve, 3);
|
124
|
+
}
|
125
|
+
|
126
|
+
|
127
|
+
// Shamelessly stolen from hash.c
|
128
|
+
static int
|
129
|
+
keys_i(VALUE key, VALUE value, VALUE ary)
|
130
|
+
{
|
131
|
+
rb_ary_push(ary, key);
|
132
|
+
return ST_CONTINUE;
|
133
|
+
}
|
134
|
+
|
135
|
+
static VALUE
|
136
|
+
rb_hash_keys(VALUE hash)
|
137
|
+
{
|
138
|
+
VALUE ary;
|
139
|
+
|
140
|
+
ary = rb_ary_new();
|
141
|
+
rb_hash_foreach(hash, keys_i, ary);
|
142
|
+
|
143
|
+
return ary;
|
144
|
+
}
|
145
|
+
|
146
|
+
|
data/lib/posix/sigset.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
class Posix
|
2
|
+
class Sigset
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@signals = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def <<(signal)
|
9
|
+
case signal
|
10
|
+
when String
|
11
|
+
signal = Signal.list[signal]
|
12
|
+
end
|
13
|
+
|
14
|
+
@signals << signal unless include? signal
|
15
|
+
end
|
16
|
+
|
17
|
+
def include?(signal)
|
18
|
+
@signals.include? signal
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
data/lib/posix.rb
ADDED
data/posix.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "posix"
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.1"
|
6
6
|
s.authors = ["Richo Healey"]
|
7
7
|
s.email = ["richo@psych0tik.net"]
|
8
8
|
s.homepage = "http://github.com/richo/ruby-posix"
|
@@ -16,8 +16,8 @@ Gem::Specification.new do |s|
|
|
16
16
|
#s.add_development_dependency "rspec"
|
17
17
|
|
18
18
|
s.files = `git ls-files`.split("\n")
|
19
|
+
s.extensions = ['ext/posix/extconf.rb']
|
19
20
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
21
|
s.require_paths = ["lib"]
|
22
22
|
end
|
23
23
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: posix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -15,10 +15,15 @@ description: Wrappers for some posix functions that I couldn't find in the stdli
|
|
15
15
|
email:
|
16
16
|
- richo@psych0tik.net
|
17
17
|
executables: []
|
18
|
-
extensions:
|
18
|
+
extensions:
|
19
|
+
- ext/posix/extconf.rb
|
19
20
|
extra_rdoc_files: []
|
20
21
|
files:
|
21
22
|
- README.md
|
23
|
+
- ext/posix/extconf.rb
|
24
|
+
- ext/posix/posix.c
|
25
|
+
- lib/posix.rb
|
26
|
+
- lib/posix/sigset.rb
|
22
27
|
- posix.gemspec
|
23
28
|
homepage: http://github.com/richo/ruby-posix
|
24
29
|
licenses: []
|