2 # -*- encoding: binary -*-
3 Encoding
.default_external
= Encoding
::BINARY if defined?(Encoding
)
4 $stderr.sync
= $stdout.sync
= true
9 commands
= %w(create attr send receive wait unlink
)
10 usage
= "Usage: MQUEUE=/name #{File.basename($0)} COMMAND " \
11 "[options] [<arguments>]\n" \
12 "COMMAND may be one of: #{commands.join(', ')}"
14 mqueue
= ENV["MQUEUE"] or abort usage
15 command
= ARGV.shift
or abort usage
16 commands
.include?(command
) or abort usage
24 command
= command
.to_sym
27 x
.banner
= usage
.split(/\n/).first
.gsub(/COMMAND/, command
.to_s
)
33 x
.on('-x', '--exclusive', "exclusive create") {
36 x
.on('-m', '--mode=MODE', "octal file mode") { |i
|
39 x
.on('-c', '--maxmsg=COUNT', Integer
, "maximum number of messages") { |i
|
40 mq_attr
||= POSIX_MQ
::Attr.new
43 x
.on('-s', '--msgsize=BYTES', Integer
, "maximum size of message") { |i
|
44 mq_attr
||= POSIX_MQ
::Attr.new
48 x
.on('-t', '--timeout=SECONDS', Float
, "timeout in seconds") { |f
|
52 conflict
= "timeout and nonblock are exclusive"
53 x
.on('-t', '--timeout=SECONDS', Float
, "timeout in seconds") { |f
|
54 abort conflict
if nonblock
57 x
.on('-n', '--nonblock', "nonblocking operation") {
58 abort conflict
if timeout
60 oflags
|= IO
::NONBLOCK
64 x
.on('-p', '--priority=PRIO', Integer
, "priority of message") { |i
|
68 x
.on('-p', '--priority', "output priority of message to stderr") {
73 x
.on('-q', "quiet warnings and errors") { $stderr.reopen("/dev/null", "w") }
74 x
.on('-h', '--help', 'Show this help message.') { puts x
; exit
}
78 trap(:INT) { exit
130 }
80 unless command
== :send || ARGV.empty
?
81 abort
"#{command} accepts no arguments"
85 if command
== :create && mq_attr
86 mq_attr
.flags
= mq_attr
.curmsgs
= 0
87 mq_attr
.msgsize
&& ! mq_attr
.maxmsg
and
88 abort
"--maxmsg must be set with --msgsize"
89 mq_attr
.maxmsg
&& ! mq_attr
.msgsize
and
90 abort
"--msgsize must be set with --maxmsg"
91 elsif command
== :unlink
92 POSIX_MQ
.unlink(mqueue
)
96 mq
= POSIX_MQ
.open(mqueue
, oflags
, mode
, mq_attr
)
101 buf
, prio
= mq
.receive("", timeout
)
102 $stderr.syswrite("priority=#{prio}\n") if priority
103 $stdout.syswrite(buf
)
105 ARGV << $stdin.read
if ARGV.empty
?
106 ARGV.each
{ |msg
| mq
.send(msg
, priority
, timeout
) }
110 "flags=#{mq_attr.flags}\n" \
111 "maxmsg=#{mq_attr.maxmsg}\n" \
112 "msgsize=#{mq_attr.msgsize}\n" \
113 "curmsgs=#{mq_attr.curmsgs}\n")
117 # we wouldn't get a notification if there were already messages
118 exit
if mq
.attr
.curmsgs
> 0
120 exit
if mq
.attr
.curmsgs
> 0 # avoid race condition
122 timeout
.nil? ? sleep
: sleep(timeout
)
128 abort
"Queue does not exist"
129 rescue Errno
::EMSGSIZE
130 abort
"Message too long"
132 abort(command
== :send ? "Queue full" : "No messages available")
133 rescue Errno
::ETIMEDOUT
134 warn
"Operation timed out"