pidfd 0.6.0
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +29 -0
- data/LICENSE +21 -0
- data/README.md +231 -0
- data/lib/pidfd/errors.rb +15 -0
- data/lib/pidfd/version.rb +6 -0
- data/lib/pidfd.rb +159 -0
- data/pidfd.gemspec +33 -0
- metadata +69 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 61a5d615dfec6deefe6cb78906b3be7887fb747696ac911c91dafabf5e123db5
|
4
|
+
data.tar.gz: 7a7a6d725b86d614ea72d61f14f19d9ad3b14a934eb5df16a7a434441d1b7224
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e7be3b9c2c7127e959ec114d9ae0d460be6ba618dc3b39c681f8e9915a03ff218f349a423571ad0e0ded86ce542469495406c32457c443ec91f498cc5efe1357
|
7
|
+
data.tar.gz: 2150b342587007ed488338afb0f5b1a818768d98faba2b3eb2a407d9ebf6753beb430d588c530ba6aa52bbe2bf84ddaa31afb2a80c5d7c4ceb8af1c48aab7e2d
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Pidfd Changelog
|
2
|
+
|
3
|
+
## 0.6.0 (2025-09-05)
|
4
|
+
- [Breaking] **BREAKING CHANGE**: Moved main API from `Pidfd::Pidfd` to `Pidfd` class
|
5
|
+
- Old: `pidfd = Pidfd::Pidfd.new(pid)` → New: `pidfd = Pidfd.new(pid)`
|
6
|
+
- Old: `Pidfd::Pidfd.supported?` → New: `Pidfd.supported?`
|
7
|
+
- Old: `Pidfd::Pidfd.pidfd_open_syscall = 434` → New: `Pidfd.pidfd_open_syscall = 434`
|
8
|
+
- Error classes remain namespaced as `Pidfd::Errors::*`
|
9
|
+
- This simplifies the API and removes redundant nested class structure
|
10
|
+
|
11
|
+
## 0.5.0 (2025-09-05)
|
12
|
+
- [Feature] Initial release extracted from Karafka framework.
|
13
|
+
- [Feature] Core pidfd functionality for Linux 5.3+.
|
14
|
+
- [Feature] `Pidfd::Pidfd` class with process management capabilities.
|
15
|
+
- [Feature] `#alive?` method for race-free process status checking.
|
16
|
+
- [Feature] `#signal` method for safe signal delivery.
|
17
|
+
- [Feature] `#cleanup` method for zombie process reaping.
|
18
|
+
- [Feature] Platform support detection via `Pidfd::Pidfd.supported?`.
|
19
|
+
- [Feature] Configurable syscall numbers for different architectures.
|
20
|
+
- [Feature] Thread-safe operations with mutex protection.
|
21
|
+
- [Feature] Non-blocking process monitoring using IO.select.
|
22
|
+
- [Feature] Comprehensive error handling with custom exceptions.
|
23
|
+
- [Feature] Full test suite with RSpec.
|
24
|
+
- [Feature] GitHub Actions CI/CD pipeline.
|
25
|
+
- [Feature] Documentation and usage examples.
|
26
|
+
- [Enhancement] Uses FFI for direct syscall bindings.
|
27
|
+
- [Enhancement] Supports pidfd_open and pidfd_send_signal syscalls.
|
28
|
+
- [Enhancement] Implements waitid for process cleanup.
|
29
|
+
- [Enhancement] Compatible with Ruby 3.2+.
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Maciej Mensfeld
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,231 @@
|
|
1
|
+
# Pidfd
|
2
|
+
|
3
|
+
[](https://rubygems.org/gems/pidfd)
|
4
|
+
[](https://github.com/mensfeld/pidfd/actions/workflows/ci.yml)
|
5
|
+
|
6
|
+
A Ruby wrapper for Linux pidfd (Process File Descriptor) system calls, providing safer process management with guaranteed process identity.
|
7
|
+
|
8
|
+
## What is pidfd?
|
9
|
+
|
10
|
+
Process file descriptors (pidfd) were introduced in Linux 5.3 (2019) to solve fundamental problems with traditional PID-based process management:
|
11
|
+
|
12
|
+
### The Problem with PIDs
|
13
|
+
|
14
|
+
Traditional Unix PIDs have a critical flaw: **PID reuse**. When a process dies, its PID can be immediately reassigned to a new, unrelated process. This creates race conditions where:
|
15
|
+
|
16
|
+
- You might send signals to the wrong process
|
17
|
+
- Process state checks become unreliable
|
18
|
+
- Security vulnerabilities can arise from PID confusion
|
19
|
+
|
20
|
+
### The pidfd Solution
|
21
|
+
|
22
|
+
Pidfds provide a **stable reference** to a process that remains valid even if the PID is reused. Key benefits:
|
23
|
+
|
24
|
+
- **Race-free signal delivery** - Signals always go to the intended process
|
25
|
+
- **Reliable process monitoring** - Know definitively when a process exits
|
26
|
+
- **Thread-safe operations** - No TOCTTOU races
|
27
|
+
- **Pollable file descriptors** - Integrate with event loops efficiently
|
28
|
+
|
29
|
+
## When to Use This Gem
|
30
|
+
|
31
|
+
Use pidfd when you need:
|
32
|
+
|
33
|
+
- **Reliable process management** in production environments
|
34
|
+
- **Non-child process monitoring** without being the parent
|
35
|
+
- **High-security applications** where PID confusion is unacceptable
|
36
|
+
- **Systems with high process churn** where PID reuse is common
|
37
|
+
- **Libraries operating in uncontrolled environments**
|
38
|
+
|
39
|
+
Don't use pidfd for:
|
40
|
+
- macOS or Windows (Linux-only feature)
|
41
|
+
- Kernels older than Linux 5.3
|
42
|
+
- Simple parent-child relationships (traditional wait works fine)
|
43
|
+
|
44
|
+
## Installation
|
45
|
+
|
46
|
+
Add this line to your application's Gemfile:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
gem 'pidfd'
|
50
|
+
```
|
51
|
+
|
52
|
+
And then execute:
|
53
|
+
|
54
|
+
```bash
|
55
|
+
bundle install
|
56
|
+
```
|
57
|
+
|
58
|
+
Or install it yourself as:
|
59
|
+
|
60
|
+
```bash
|
61
|
+
gem install pidfd
|
62
|
+
```
|
63
|
+
|
64
|
+
## Requirements
|
65
|
+
|
66
|
+
- Linux kernel 5.3 or newer
|
67
|
+
- Ruby 3.2 or newer
|
68
|
+
- FFI gem
|
69
|
+
|
70
|
+
## Usage
|
71
|
+
|
72
|
+
### Basic Process Management
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
require 'pidfd'
|
76
|
+
|
77
|
+
# Create a pidfd for a process
|
78
|
+
process = fork { sleep 10 }
|
79
|
+
pidfd = Pidfd.new(process)
|
80
|
+
|
81
|
+
# Check if process is alive
|
82
|
+
pidfd.alive? # => true
|
83
|
+
|
84
|
+
# Send a signal safely
|
85
|
+
pidfd.signal('TERM') # => true (signal sent)
|
86
|
+
|
87
|
+
# Clean up zombie process after it exits
|
88
|
+
pidfd.cleanup
|
89
|
+
```
|
90
|
+
|
91
|
+
### Monitoring Non-Child Processes
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
# Monitor any process by PID (requires appropriate permissions)
|
95
|
+
nginx_pid = File.read('/var/run/nginx.pid').to_i
|
96
|
+
pidfd = Pidfd.new(nginx_pid)
|
97
|
+
|
98
|
+
# Check status without race conditions
|
99
|
+
if pidfd.alive?
|
100
|
+
puts "Nginx is running"
|
101
|
+
else
|
102
|
+
puts "Nginx has stopped"
|
103
|
+
pidfd.cleanup
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
### Safe Signal Delivery
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
# Traditional approach (UNSAFE - race condition)
|
111
|
+
Process.kill('TERM', pid) # Might hit wrong process if PID was reused!
|
112
|
+
|
113
|
+
# Pidfd approach (SAFE)
|
114
|
+
pidfd = Pidfd.new(pid)
|
115
|
+
pidfd.signal('TERM') # Guaranteed to hit the right process or fail safely
|
116
|
+
```
|
117
|
+
|
118
|
+
### Integration with Event Loops
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
# Pidfd provides a pollable file descriptor
|
122
|
+
pidfd = Pidfd.new(child_pid)
|
123
|
+
|
124
|
+
# Use with IO.select for non-blocking monitoring
|
125
|
+
loop do
|
126
|
+
if pidfd.alive?
|
127
|
+
# Process still running
|
128
|
+
sleep 0.1
|
129
|
+
else
|
130
|
+
# Process exited
|
131
|
+
pidfd.cleanup
|
132
|
+
break
|
133
|
+
end
|
134
|
+
end
|
135
|
+
```
|
136
|
+
|
137
|
+
## Platform Support
|
138
|
+
|
139
|
+
### Checking Support
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
if Pidfd.supported?
|
143
|
+
puts "pidfd is supported on this system"
|
144
|
+
else
|
145
|
+
puts "pidfd is not available (wrong OS or kernel version)"
|
146
|
+
end
|
147
|
+
```
|
148
|
+
|
149
|
+
### Fallback Strategy
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
def safe_process_check(pid)
|
153
|
+
if Pidfd.supported?
|
154
|
+
pidfd = Pidfd.new(pid)
|
155
|
+
result = pidfd.alive?
|
156
|
+
pidfd.cleanup unless result
|
157
|
+
result
|
158
|
+
else
|
159
|
+
# Fallback to traditional (less safe) approach
|
160
|
+
Process.kill(0, pid)
|
161
|
+
true
|
162
|
+
rescue Errno::ESRCH
|
163
|
+
false
|
164
|
+
end
|
165
|
+
end
|
166
|
+
```
|
167
|
+
|
168
|
+
## Configuration
|
169
|
+
|
170
|
+
### Custom Syscall Numbers
|
171
|
+
|
172
|
+
Different architectures may use different syscall numbers. You can configure them:
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
# Default values for x86_64
|
176
|
+
Pidfd.pidfd_open_syscall = 434
|
177
|
+
Pidfd.pidfd_signal_syscall = 424
|
178
|
+
|
179
|
+
# For other architectures, consult your system headers
|
180
|
+
```
|
181
|
+
|
182
|
+
## Error Handling
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
begin
|
186
|
+
pidfd = Pidfd.new(pid)
|
187
|
+
rescue Pidfd::Errors::PidfdOpenFailedError => e
|
188
|
+
# Process doesn't exist or permission denied
|
189
|
+
puts "Could not open pidfd: #{e.message}"
|
190
|
+
end
|
191
|
+
|
192
|
+
begin
|
193
|
+
pidfd.signal('TERM')
|
194
|
+
rescue Pidfd::Errors::PidfdSignalFailedError => e
|
195
|
+
# Signal delivery failed
|
196
|
+
puts "Could not send signal: #{e.message}"
|
197
|
+
end
|
198
|
+
```
|
199
|
+
|
200
|
+
## Performance Considerations
|
201
|
+
|
202
|
+
- **Efficient**: Pidfd operations are kernel-level, very fast
|
203
|
+
- **Low overhead**: Minimal memory usage per pidfd
|
204
|
+
- **Scalable**: Handles thousands of processes efficiently
|
205
|
+
- **Non-blocking**: Supports async operation patterns
|
206
|
+
|
207
|
+
## Security
|
208
|
+
|
209
|
+
Pidfd provides significant security improvements:
|
210
|
+
|
211
|
+
- Prevents signal delivery to wrong processes
|
212
|
+
- Eliminates PID confusion attacks
|
213
|
+
- Provides capability-based process references
|
214
|
+
- Works with Linux security modules (SELinux, AppArmor)
|
215
|
+
|
216
|
+
## Further Reading
|
217
|
+
|
218
|
+
- [Linux pidfd documentation](https://man7.org/linux/man-pages/man2/pidfd_open.2.html)
|
219
|
+
- [LWN: Process-descriptor file descriptors](https://lwn.net/Articles/801319/)
|
220
|
+
- [Bringing Linux pidfd to Ruby](https://mensfeld.github.io/bringing_linux_pidfd_to_ruby/)
|
221
|
+
|
222
|
+
## Author
|
223
|
+
|
224
|
+
Based on the pidfd implementation in [Karafka](https://github.com/karafka/karafka) by Maciej Mensfeld.
|
225
|
+
|
226
|
+
## Acknowledgments
|
227
|
+
|
228
|
+
Special thanks to:
|
229
|
+
- The Linux kernel team for implementing pidfd
|
230
|
+
- KJ Tsanaktsidis for Ruby core contributions discussions
|
231
|
+
- The Karafka community for battle-testing this implementation
|
data/lib/pidfd/errors.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Pidfd
|
4
|
+
# Namespace for all the pidfd errors
|
5
|
+
module Errors
|
6
|
+
# Base error class for all pidfd errors
|
7
|
+
BaseError = Class.new(StandardError)
|
8
|
+
|
9
|
+
# Error raised when pidfd_open syscall fails
|
10
|
+
PidfdOpenFailedError = Class.new(BaseError)
|
11
|
+
|
12
|
+
# Error raised when pidfd_signal syscall fails
|
13
|
+
PidfdSignalFailedError = Class.new(BaseError)
|
14
|
+
end
|
15
|
+
end
|
data/lib/pidfd.rb
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
|
5
|
+
# Main class that wraps Linux pidfd functionality for Ruby
|
6
|
+
class Pidfd
|
7
|
+
extend FFI::Library
|
8
|
+
|
9
|
+
begin
|
10
|
+
ffi_lib FFI::Library::LIBC
|
11
|
+
|
12
|
+
# direct usage of this is only available since glibc 2.36, hence we use bindings and call
|
13
|
+
# it directly via syscalls
|
14
|
+
attach_function :fdpid_open, :syscall, %i[long int uint], :int
|
15
|
+
attach_function :fdpid_signal, :syscall, %i[long int int pointer uint], :int
|
16
|
+
attach_function :waitid, %i[int int pointer uint], :int
|
17
|
+
|
18
|
+
API_SUPPORTED = true
|
19
|
+
# LoadError is a parent to FFI::NotFoundError
|
20
|
+
rescue LoadError
|
21
|
+
API_SUPPORTED = false
|
22
|
+
ensure
|
23
|
+
private_constant :API_SUPPORTED
|
24
|
+
end
|
25
|
+
|
26
|
+
# https://github.com/torvalds/linux/blob/7e90b5c295/include/uapi/linux/wait.h#L20
|
27
|
+
P_PIDFD = 3
|
28
|
+
|
29
|
+
# Wait for child processes that have exited
|
30
|
+
WEXITED = 4
|
31
|
+
|
32
|
+
# Default syscall numbers for x86_64 Linux
|
33
|
+
# These can be overridden if needed for different architectures
|
34
|
+
# Pidfd open call number
|
35
|
+
DEFAULT_PIDFD_OPEN_SYSCALL = 434
|
36
|
+
|
37
|
+
# Pidfd signal call number
|
38
|
+
DEFAULT_PIDFD_SIGNAL_SYSCALL = 424
|
39
|
+
|
40
|
+
private_constant :P_PIDFD, :WEXITED
|
41
|
+
|
42
|
+
class << self
|
43
|
+
# @return [Integer] syscall number for pidfd_open
|
44
|
+
attr_accessor :pidfd_open_syscall
|
45
|
+
|
46
|
+
# @return [Integer] syscall number for pidfd_signal
|
47
|
+
attr_accessor :pidfd_signal_syscall
|
48
|
+
|
49
|
+
# @return [Boolean] true if syscall is supported via FFI
|
50
|
+
def supported?
|
51
|
+
# If we were not even able to load the FFI C lib, it won't be supported
|
52
|
+
return false unless API_SUPPORTED
|
53
|
+
# Won't work on macOS because it does not support pidfd
|
54
|
+
return false if RUBY_DESCRIPTION.include?('darwin')
|
55
|
+
# Won't work on Windows for the same reason as on macOS
|
56
|
+
return false if RUBY_DESCRIPTION.match?(/mswin|ming|cygwin/)
|
57
|
+
|
58
|
+
# There are some OSes like BSD that will have C lib for FFI bindings but will not support
|
59
|
+
# the needed syscalls. In such cases, we can just try and fail, which will indicate it
|
60
|
+
# won't work. The same applies to using new glibc on an old kernel.
|
61
|
+
new(::Process.pid)
|
62
|
+
|
63
|
+
true
|
64
|
+
rescue Errors::PidfdOpenFailedError
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Set default syscall numbers
|
70
|
+
self.pidfd_open_syscall = DEFAULT_PIDFD_OPEN_SYSCALL
|
71
|
+
self.pidfd_signal_syscall = DEFAULT_PIDFD_SIGNAL_SYSCALL
|
72
|
+
|
73
|
+
# @param pid [Integer] pid of the node we want to work with
|
74
|
+
def initialize(pid)
|
75
|
+
@mutex = Mutex.new
|
76
|
+
|
77
|
+
@pid = pid
|
78
|
+
@pidfd = open_pidfd(pid)
|
79
|
+
@pidfd_io = IO.new(@pidfd)
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [Boolean] true if given process is alive, false if no longer
|
83
|
+
def alive?
|
84
|
+
@pidfd_select ||= [@pidfd_io]
|
85
|
+
|
86
|
+
if @mutex.owned?
|
87
|
+
return false if @cleaned
|
88
|
+
|
89
|
+
IO.select(@pidfd_select, nil, nil, 0).nil?
|
90
|
+
else
|
91
|
+
@mutex.synchronize do
|
92
|
+
return false if @cleaned
|
93
|
+
|
94
|
+
IO.select(@pidfd_select, nil, nil, 0).nil?
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Cleans the zombie process
|
100
|
+
# @note This should run **only** on processes that exited, otherwise will wait
|
101
|
+
def cleanup
|
102
|
+
@mutex.synchronize do
|
103
|
+
return if @cleaned
|
104
|
+
|
105
|
+
waitid(P_PIDFD, @pidfd, nil, WEXITED)
|
106
|
+
|
107
|
+
@pidfd_io.close
|
108
|
+
@pidfd_select = nil
|
109
|
+
@pidfd_io = nil
|
110
|
+
@pidfd = nil
|
111
|
+
@cleaned = true
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Sends given signal to the process using its pidfd
|
116
|
+
# @param sig_name [String] signal name
|
117
|
+
# @return [Boolean] true if signal was sent, otherwise false or error raised. `false`
|
118
|
+
# returned when we attempt to send a signal to a dead process
|
119
|
+
# @note It will not send signals to dead processes
|
120
|
+
def signal(sig_name)
|
121
|
+
@mutex.synchronize do
|
122
|
+
return false if @cleaned
|
123
|
+
# Never signal processes that are dead
|
124
|
+
return false unless alive?
|
125
|
+
|
126
|
+
result = fdpid_signal(
|
127
|
+
self.class.pidfd_signal_syscall,
|
128
|
+
@pidfd,
|
129
|
+
Signal.list.fetch(sig_name),
|
130
|
+
nil,
|
131
|
+
0
|
132
|
+
)
|
133
|
+
|
134
|
+
return true if result.zero?
|
135
|
+
|
136
|
+
raise Errors::PidfdSignalFailedError, result
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
# Opens a pidfd for the provided pid
|
143
|
+
# @param pid [Integer]
|
144
|
+
# @return [Integer] pidfd
|
145
|
+
def open_pidfd(pid)
|
146
|
+
pidfd = fdpid_open(
|
147
|
+
self.class.pidfd_open_syscall,
|
148
|
+
pid,
|
149
|
+
0
|
150
|
+
)
|
151
|
+
|
152
|
+
return pidfd if pidfd != -1
|
153
|
+
|
154
|
+
raise Errors::PidfdOpenFailedError, pidfd
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
require_relative 'pidfd/version'
|
159
|
+
require_relative 'pidfd/errors'
|
data/pidfd.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/pidfd/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'pidfd'
|
7
|
+
spec.version = Pidfd::VERSION
|
8
|
+
spec.authors = ['Maciej Mensfeld']
|
9
|
+
spec.email = ['maciej@mensfeld.pl']
|
10
|
+
|
11
|
+
spec.summary = 'Ruby wrapper for Linux pidfd system calls'
|
12
|
+
spec.homepage = 'https://github.com/mensfeld/pidfd'
|
13
|
+
spec.license = 'MIT'
|
14
|
+
spec.description = <<~DESC
|
15
|
+
Provides race-free process management using Linux pidfd (process file descriptors) for safer
|
16
|
+
signal delivery and process monitoring
|
17
|
+
DESC
|
18
|
+
|
19
|
+
spec.required_ruby_version = '>= 3.2.0'
|
20
|
+
|
21
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
22
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
23
|
+
spec.metadata['source_code_uri'] = 'https://github.com/mensfeld/pidfd'
|
24
|
+
spec.metadata['changelog_uri'] = 'https://github.com/mensfeld/pidfd/blob/main/CHANGELOG.md'
|
25
|
+
spec.metadata['documentation_uri'] = 'https://github.com/mensfeld/pidfd#readme'
|
26
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
27
|
+
|
28
|
+
# Specify which files should be added to the gem when it is released.
|
29
|
+
spec.files = Dir.glob('{lib}/**/*') + %w[LICENSE CHANGELOG.md README.md pidfd.gemspec]
|
30
|
+
spec.require_paths = ['lib']
|
31
|
+
|
32
|
+
spec.add_dependency 'ffi', '>= 1.15'
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pidfd
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.6.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Maciej Mensfeld
|
8
|
+
bindir: bin
|
9
|
+
cert_chain: []
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: ffi
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '1.15'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '1.15'
|
26
|
+
description: |
|
27
|
+
Provides race-free process management using Linux pidfd (process file descriptors) for safer
|
28
|
+
signal delivery and process monitoring
|
29
|
+
email:
|
30
|
+
- maciej@mensfeld.pl
|
31
|
+
executables: []
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- CHANGELOG.md
|
36
|
+
- LICENSE
|
37
|
+
- README.md
|
38
|
+
- lib/pidfd.rb
|
39
|
+
- lib/pidfd/errors.rb
|
40
|
+
- lib/pidfd/version.rb
|
41
|
+
- pidfd.gemspec
|
42
|
+
homepage: https://github.com/mensfeld/pidfd
|
43
|
+
licenses:
|
44
|
+
- MIT
|
45
|
+
metadata:
|
46
|
+
homepage_uri: https://github.com/mensfeld/pidfd
|
47
|
+
allowed_push_host: https://rubygems.org
|
48
|
+
source_code_uri: https://github.com/mensfeld/pidfd
|
49
|
+
changelog_uri: https://github.com/mensfeld/pidfd/blob/main/CHANGELOG.md
|
50
|
+
documentation_uri: https://github.com/mensfeld/pidfd#readme
|
51
|
+
rubygems_mfa_required: 'true'
|
52
|
+
rdoc_options: []
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 3.2.0
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
requirements: []
|
66
|
+
rubygems_version: 3.7.0
|
67
|
+
specification_version: 4
|
68
|
+
summary: Ruby wrapper for Linux pidfd system calls
|
69
|
+
test_files: []
|