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"