Imported File#ftype spec from rubyspecs.
[rbx.git] / lib / syslog.rb.ffi
blob10c8dcc313c9b9dfc3e50b7dbb47e7b582d47ffe
1 #  Created by Ari Brown on 2008-02-23.
2 #  For rubinius. All pwnage reserved.
3 #  
4 #  Used in pwning teh nubs with FFI instead of C
6 # ** Syslog(Module)
8 # Included Modules: Syslog::Constants
10 # require 'syslog'
12 # A Simple wrapper for the UNIX syslog system calls that might be handy
13 # if you're writing a server in Ruby.  For the details of the syslog(8)
14 # architecture and constants, see the syslog(3) manual page of your
15 # platform.
17 module Syslog
18   
19   module Constants
20     @@@
21     constants do |c|
22       c.include 'syslog.h'
24       c.const 'LOG_EMERG'
25       c.const 'LOG_ALERT'
26       c.const 'LOG_ERR'
27       c.const 'LOG_CRIT'
28       c.const 'LOG_WARNING'
29       c.const 'LOG_NOTICE'
30       c.const 'LOG_INFO'
31       c.const 'LOG_DEBUG'
32       c.const 'LOG_PID'
33       c.const 'LOG_CONS'
34       c.const 'LOG_ODELAY'
35       c.const 'LOG_NODELAY'
36       c.const 'LOG_NOWAIT'
37       c.const 'LOG_PERROR'
38       c.const 'LOG_AUTH'
39       c.const 'LOG_AUTHPRIV'
40       c.const 'LOG_CONSOLE'
41       c.const 'LOG_CRON'
42       c.const 'LOG_DAEMON'
43       c.const 'LOG_FTP'
44       c.const 'LOG_KERN'
45       c.const 'LOG_LPR'
46       c.const 'LOG_MAIL'
47       c.const 'LOG_NEWS'
48       c.const 'LOG_NTP'
49       c.const 'LOG_SECURITY'
50       c.const 'LOG_SYSLOG'
51       c.const 'LOG_USER'
52       c.const 'LOG_UUCP'
53       c.const 'LOG_LOCAL0'
54       c.const 'LOG_LOCAL1'
55       c.const 'LOG_LOCAL2'
56       c.const 'LOG_LOCAL3'
57       c.const 'LOG_LOCAL4'
58       c.const 'LOG_LOCAL5'
59       c.const 'LOG_LOCAL6'
60       c.const 'LOG_LOCAL7'
61     end
62     @@@
63   end
64   
65   include Constants
66   
67   module Foreign
68     # methods
69     attach_function "openlog", :open, [:string, :int, :int], :void
70     attach_function "closelog", :close, [], :void
71     attach_function "syslog", :write, [:int, :string, :string], :void
72     attach_function "setlogmask", :set_mask, [:int], :int
73   end
74   
75   class << self
77     ##
78     # returns the ident of the last open call
79     attr_reader :ident
80     
81     ##
82     # returns the options of the last open call
83     attr_reader :options
85     ##
86     # returns the facility of the last open call
87     attr_reader :facility
89     ##
90     # mask
91     #   mask=(mask)
92     #
93     # Returns or sets the log priority mask.  The value of the mask
94     # is persistent and will not be reset by Syslog::open or
95     # Syslog::close.
96     #
97     # Example:
98     #   Syslog.mask = Syslog::LOG_UPTO(Syslog::LOG_ERR)
99     def mask; @mask ||= -1; end
100     attr_writer :mask
102     ##
103     #   open(ident = $0, logopt = Syslog::LOG_PID | Syslog::LOG_CONS, facility = Syslog::LOG_USER) [{ |syslog| ... }]
104     #
105     # Opens syslog with the given options and returns the module
106     # itself.  If a block is given, calls it with an argument of
107     # itself.  If syslog is already opened, raises RuntimeError.
108     #
109     # Examples:
110     #   Syslog.open('ftpd', Syslog::LOG_PID | Syslog::LOG_NDELAY, Syslog::LOG_FTP)
111     #   open!(ident = $0, logopt = Syslog::LOG_PID | Syslog::LOG_CONS, facility = Syslog::LOG_USER)
112     #   reopen(ident = $0, logopt = Syslog::LOG_PID | Syslog::LOG_CONS, facility = Syslog::LOG_USER)
113     def open(ident=nil, opt=nil, fac=nil)
114       raise "Syslog already open" unless not @opened
116       ident ||= $0
117       opt ||= Constants::LOG_PID | Constants::LOG_CONS
118       fac ||= Constants::LOG_USER
120       @ident = ident
121       @options = opt
122       @facility = fac
124       Foreign.open(ident, opt, fac)
126       @opened = true
128       # Calling set_mask twice is the standard way to set the 'default' mask
129       @mask = Foreign.set_mask(0)
130       Foreign.set_mask(@mask)
132       if block_given?
133         begin
134           yield self
135         ensure
136           close
137         end
138       end
140       self
141     end
142     alias_method :open!, :open
144     ##
145     # like open, but closes it first
146     def reopen(*args)
147       close
148       open(*args)
149     end
151     ##
152     # Is it open?
153     def opened?
154       @opened
155     end
157     ##
158     # Close the log
159     # close will raise an error if it is already closed
160     def close
161       raise "Syslog not opened" unless @opened
163       Foreign.close
164       @ident = nil
165       @options = @facility = @mask = -1;
166       @opened = false
167     end
169     ##
170     #   log(Syslog::LOG_CRIT, "The %s is falling!", "sky")
171     #  
172     # Doesn't take any platform specific printf statements
173     #   logs things to $stderr
174     #   log(Syslog::LOG_CRIT, "Welcome, %s, to my %s!", "leethaxxor", "lavratory")
175     def log(pri, *args)
176       write(pri, *args)
177     end
179     ##
180     # handy little shortcut for LOG_EMERG as the priority
181     def emerg(*args);  Foreign.write(LOG_EMERG,   *args); end
183     ##
184     # handy little shortcut for LOG_ALERT as the priority
185     def alert(*args);  Foreign.write(LOG_ALERT,   *args); end
187     ##
188     # handy little shortcut for LOG_ERR as the priority
189     def err(*args);    Foreign.write(LOG_ERR,     *args); end
191     ##
192     # handy little shortcut for LOG_CRIT as the priority
193     def crit(*args);   Foreign.write(LOG_CRIT,    *args); end
195     ##
196     # handy little shortcut for LOG_WARNING as the priority
197     def warning(*args);Foreign.write(LOG_WARNING, *args); end
199     ##
200     # handy little shortcut for LOG_NOTICE as the priority
201     def notice(*args); Foreign.write(LOG_NOTICE,  *args); end
203     ##
204     # handy little shortcut for LOG_INFO as the priority
205     def info(*args);   Foreign.write(LOG_INFO,    *args); end
207     ##
208     # handy little shortcut for LOG_DEBUG as the priority
209     def debug(*args);  Foreign.write(LOG_DEBUG,   *args); end
211     ##
212     #   LOG_MASK(pri)
213     #
214     # HACK copied from macro
215     # Creates a mask for one priority.
216     def LOG_MASK(pri)
217       1 << pri
218     end
220     ##
221     #   LOG_UPTO(pri)
222     # HACK copied from macro
223     # Creates a mask for all priorities up to pri.
224     def LOG_UPTO(pri)
225       (1 << ((pri)+1)) - 1
226     end
228     def inspect
229       if @opened
230         "#<%s: opened=true, ident=\"%s\", options=%d, facility=%d, mask=%d>" %
231         [self.name, @ident, @options, @facility, @mask]
232       else
233         "#<#{self.name}: opened=false>"
234       end
235     end
237     ##
238     #   Syslog.instance # => Syslog
239     # Returns the Syslog module
240     def instance
241       self
242     end
244     def write(pri, format, *args)
245       raise "Syslog must be opened before write" unless @opened
247       message = format % args
248       Foreign.write(pri, "%s", message)
249     end
250     private :write
251   end