2 # -*- encoding: binary -*-
3 $stderr.sync
= $stdout.sync
= true
11 commands
= %w(create attr send receive wait unlink
)
12 usage
= "Usage: MQUEUE=/name #{File.basename($0)} COMMAND " \
13 "[options] [<arguments>]\n" \
14 "COMMAND may be one of: #{commands.join(', ')}"
16 mqueue
= ENV["MQUEUE"] or abort usage
17 command
= ARGV.shift
or abort usage
18 commands
.include?(command
) or abort usage
26 command
= command
.to_sym
29 x
.banner
= usage
.split(/\n/).first
.gsub(/COMMAND/, command
.to_s
)
35 x
.on('-x', '--exclusive', "exclusive create") {
38 x
.on('-m', '--mode=MODE', "octal file mode") { |i
|
41 x
.on('-c', '--maxmsg=COUNT', Integer
, "maximum number of messages") { |i
|
42 mq_attr
||= POSIX_MQ
::Attr.new
45 x
.on('-s', '--msgsize=BYTES', Integer
, "maximum size of message") { |i
|
46 mq_attr
||= POSIX_MQ
::Attr.new
50 x
.on('-t', '--timeout=SECONDS', Float
, "timeout in seconds") { |f
|
54 conflict
= "timeout and nonblock are exclusive"
55 x
.on('-t', '--timeout=SECONDS', Float
, "timeout in seconds") { |f
|
56 abort conflict
if nonblock
59 x
.on('-n', '--nonblock', "nonblocking operation") {
60 abort conflict
if timeout
62 oflags
|= IO
::NONBLOCK
66 x
.on('-p', '--priority=PRIO', Integer
, "priority of message") { |i
|
70 x
.on('-p', '--priority', "output priority of message to stderr") {
75 x
.on('-q', "quiet warnings and errors") { $stderr.reopen("/dev/null", "wb") }
76 x
.on('-h', '--help', 'Show this help message.') { puts x
; exit
}
80 trap(:INT) { exit
130 }
82 unless command
== :send || ARGV.empty
?
83 abort
"#{command} accepts no arguments"
87 if command
== :create && mq_attr
88 mq_attr
.flags
= mq_attr
.curmsgs
= 0
89 mq_attr
.msgsize
&& ! mq_attr
.maxmsg
and
90 abort
"--maxmsg must be set with --msgsize"
91 mq_attr
.maxmsg
&& ! mq_attr
.msgsize
and
92 abort
"--msgsize must be set with --maxmsg"
93 elsif command
== :unlink
94 POSIX_MQ
.unlink(mqueue
)
98 mq
= POSIX_MQ
.open(mqueue
, oflags
, mode
, mq_attr
)
103 buf
, prio
= mq
.receive("", timeout
)
104 $stderr.write("priority=#{prio}\n") if priority
107 ARGV << $stdin.read
if ARGV.empty
?
108 ARGV.each
{ |msg
| mq
.send(msg
, priority
, timeout
) }
112 "flags=#{mq_attr.flags}\n" \
113 "maxmsg=#{mq_attr.maxmsg}\n" \
114 "msgsize=#{mq_attr.msgsize}\n" \
115 "curmsgs=#{mq_attr.curmsgs}\n")
119 # we wouldn't get a notification if there were already messages
120 exit
if mq
.attr
.curmsgs
> 0
122 exit
if mq
.attr
.curmsgs
> 0 # avoid race condition
124 timeout
.nil? ? sleep
: sleep(timeout
)
130 abort
"Queue does not exist"
131 rescue Errno
::EMSGSIZE
132 abort
"Message too long"
134 abort(command
== :send ? "Queue full" : "No messages available")
135 rescue Errno
::ETIMEDOUT
136 warn
"Operation timed out"