plist4r 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,12 +12,12 @@ module Plist4r
12
12
 
13
13
  def hash hash=nil
14
14
  case hash
15
- when ::ActiveSupport::OrderedHash
15
+ when ::Plist4r::OrderedHash
16
16
  @hash = @orig = hash
17
17
  when nil
18
18
  @hash
19
19
  else
20
- raise "Must hash be an ::ActiveSupport::OrderedHash"
20
+ raise "Must hash be an ::Plist4r::OrderedHash"
21
21
  end
22
22
  end
23
23
 
@@ -25,6 +25,27 @@ module Plist4r
25
25
  raise "Method not implemented #{method_name.to_sym.inspect}, for class #{self.inspect}"
26
26
  end
27
27
 
28
+ # A Hash Array of the supported plist keys for this type. These are only those plist keys
29
+ # recognized as belonging to a specific plist datatype. Used in validation, part of DataMethods.
30
+ # We usually overload this method in subclasses of {Plist4r::PlistType}.
31
+ # @example
32
+ # class Plist4r::PlistType::MyPlistType < PlistType
33
+ # def self.valid_keys
34
+ # {
35
+ # :string => %w[PlistKeyS1 PlistKeyS2 ...],
36
+ # :bool => %w[PlistKeyB1 PlistKeyB2 ...],
37
+ # :integer => %w[PlistKeyI1 PlistKeyI2 ...],
38
+ # :method_defined => %w[CustomPlistKey1 CustomPlistKey2 ...]
39
+ # }
40
+ # end
41
+ # end
42
+ #
43
+ # plist.plist_type :my_plist_type
44
+ # plist.plist_key_s1 "some string"
45
+ # plist.plist_key_b1 true
46
+ # plist.plist_key_i1 08
47
+ # plist.custom_plist_key1 MyClass.new(opts)
48
+ #
28
49
  def valid_keys
29
50
  self.class.valid_keys
30
51
  end
@@ -60,7 +81,7 @@ module Plist4r
60
81
  # puts "@enclosing_block = #{@enclosing_block}"
61
82
 
62
83
  @block = blk
63
- @hash = ::ActiveSupport::OrderedHash.new
84
+ @hash = ::Plist4r::OrderedHash.new
64
85
  # puts "@hash = #{@hash}"
65
86
 
66
87
  instance_eval(&@block) if @block
@@ -84,7 +105,7 @@ module Plist4r
84
105
  end
85
106
 
86
107
  def unselect_all
87
- @hash = ::ActiveSupport::OrderedHash.new
108
+ @hash = ::Plist4r::OrderedHash.new
88
109
  end
89
110
 
90
111
  def select_all
@@ -4,6 +4,9 @@ require 'plist4r/plist_type'
4
4
  module Plist4r
5
5
  class PlistType::Launchd < PlistType
6
6
 
7
+ # A Hash Array of the supported plist keys for this type. These are the plist keys are recognized to belong to a Launchd plist.
8
+ # Used in validation, categorized by the value's DataType.
9
+ # @see Plist4r::DataMethods
7
10
  def self.valid_keys
8
11
  {
9
12
  :string => %w[Label UserName GroupName LimitLoadToSessionType Program RootDirectory WorkingDirectory StandardInPath StandardOutPath StandardErrorPath],
@@ -14,16 +17,21 @@ module Plist4r
14
17
  }
15
18
  end
16
19
 
17
- # :call-seq:
18
- # inetdCompatibility({:wait => true})
19
- # inetdCompatibility -> hash or nil
20
- #
21
- # inetd_compatibility <hash>
20
+ # Set or return the plist key "inetdCompatibility"
21
+ # @param [Hash <true,false>] value the
22
22
  # The presence of this key specifies that the daemon expects to be run as if it were launched from inetd.
23
23
  #
24
- # :wait <boolean>
24
+ # @option value [true,false] :wait (nil)
25
25
  # This flag corresponds to the "wait" or "nowait" option of inetd. If true, then the listening socket is passed via the standard in/out/error file descriptors.
26
26
  # If false, then accept(2) is called on behalf of the job, and the result is passed via the standard in/out/error descriptors.
27
+ #
28
+ # @example
29
+ # # set inetdCompatibility
30
+ # launchd_plist.inetdCompatibility({:wait => true})
31
+ #
32
+ # # return inetdCompatibility
33
+ # launchd_plist.inetdCompatibility => hash or nil
34
+ #
27
35
  def inetd_compatibility value=nil
28
36
  key = "inetdCompatibility"
29
37
  case value
@@ -39,7 +47,7 @@ module Plist4r
39
47
  raise "Invalid value: #{method_name} #{value.inspect}. Should be: #{method_name} :wait => true|false"
40
48
  end
41
49
  end
42
-
50
+
43
51
  class KeepAlive < ArrayDict
44
52
  def valid_keys
45
53
  {
@@ -49,47 +57,52 @@ module Plist4r
49
57
  end
50
58
  end
51
59
 
52
- # :call-seq:
53
- # keep_alive(true)
54
- # keep_alive(false)
55
- # keep_alive { block_of_keys }
56
- # keep_alive => true, false, Hash, or nil
60
+ # Set or return the plist key "KeepAlive"
57
61
  #
58
- # keep_alive <boolean or block of keys>
62
+ # @param [true, false, Hash] value
59
63
  # This optional key is used to control whether your job is to be kept continuously running or to let demand and conditions control the invocation. The default is
60
64
  # false and therefore only demand will start the job. The value may be set to true to unconditionally keep the job alive. Alternatively, a dictionary of conditions
61
65
  # may be specified to selectively control whether launchd keeps a job alive or not. If multiple keys are provided, launchd ORs them, thus providing maximum flexibil-
62
66
  # ity to the job to refine the logic and stall if necessary. If launchd finds no reason to restart the job, it falls back on demand based invocation. Jobs that exit
63
67
  # quickly and frequently when configured to be kept alive will be throttled to converve system resources.
64
68
  #
65
- # keep_alive do
66
- #
67
- # successful_exit <boolean>
69
+ # @option value [true,false] :successful_exit (nil)
68
70
  # If true, the job will be restarted as long as the program exits and with an exit status of zero. If false, the job will be restarted in the inverse condi-
69
71
  # tion. This key implies that "RunAtLoad" is set to true, since the job needs to run at least once before we can get an exit status.
70
72
  #
71
- # network_state <boolean>
73
+ # @option value [true,false] :network_state (nil)
72
74
  # If true, the job will be kept alive as long as the network is up, where up is defined as at least one non-loopback interface being up and having IPv4 or IPv6
73
75
  # addresses assigned to them. If false, the job will be kept alive in the inverse condition.
74
76
  #
77
+ # @option value [Hash <true,false>] :path_state (nil)
75
78
  # path_state <hash of booleans>
76
79
  # Each key in this dictionary is a file-system path. If the value of the key is true, then the job will be kept alive as long as the path exists. If false, the
77
80
  # job will be kept alive in the inverse condition. The intent of this feature is that two or more jobs may create semaphores in the file-system namespace.
78
81
  #
82
+ # @option value [Hash <true,false>] :other_job_enabled (nil)
79
83
  # other_job_enabled <hash of booleans>
80
84
  # Each key in this dictionary is the label of another job. If the value of the key is true, then this job is kept alive as long as that other job is enabled.
81
85
  # Otherwise, if the value is false, then this job is kept alive as long as the other job is disabled. This feature should not be considered a substitute for
82
86
  # the use of IPC.
83
87
  #
84
- # end
88
+ # @example
89
+ # # set KeepAlive (boolean)
90
+ #
91
+ # launchd_plist.keep_alive(true)
92
+ # launchd_plist.keep_alive(false)
85
93
  #
86
- # Example:
94
+ # # return KeepAlive
95
+ # launchd_plist.keep_alive => true, false, Hash, or nil
87
96
  #
88
- # keep_alive do
89
- # successful_exit true
90
- # network_state false
91
- # end
97
+ # @example
98
+ # # set KeepAlive (hash of values)
92
99
  #
100
+ # launchd_plist.keep_alive do
101
+ # successful_exit true
102
+ # network_state false
103
+ # path_state { "/path1" => true, "/path2" => false }
104
+ # other_job_enabled { "notifyd" => true, "syslogd" => true }
105
+ # end
93
106
  def keep_alive value=nil, &blk
94
107
  key = "KeepAlive"
95
108
 
@@ -98,7 +111,7 @@ module Plist4r
98
111
  @hash[key] = value
99
112
  when nil
100
113
  if blk
101
- @hash[key] ||= ::ActiveSupport::OrderedHash.new
114
+ @hash[key] ||= ::Plist4r::OrderedHash.new
102
115
  @hash[key] = ::LaunchdPlistStructs::KeepAlive.new(@hash[key],&blk).hash
103
116
  else
104
117
  @hash[key]
@@ -108,11 +121,16 @@ module Plist4r
108
121
  end
109
122
  end
110
123
 
111
- # :call-seq:
112
- # environment_variables({"VAR1" => "VAL1", "VAR2" => "VAL2"})
113
- # environment_variables -> hash or nil
124
+ # Set or return the plist key "EnvironmentVariables"
125
+ #
126
+ # @example
127
+ # # Set environment variables
128
+ # launchd_plist.environment_variables({ "VAR1" => "VAL1", "VAR2" => "VAL2" })
114
129
  #
115
- # environment_variables <hash of strings>
130
+ # # Return environment variables
131
+ # launchd_plist.environment_variables => { "VAR1" => "VAL1", "VAR2" => "VAL2" }
132
+ #
133
+ # @param [Hash <String>] value
116
134
  # This optional key is used to specify additional environmental variables to be set before running the job.
117
135
  def environment_variables value=nil, &blk
118
136
  key = "EnvironmentVariables"
@@ -140,47 +158,55 @@ module Plist4r
140
158
  end
141
159
  end
142
160
 
143
- # :call-seq:
144
- # start_calendar_interval(array_index=nil) { block_of_keys }
145
- # start_calendar_interval -> array or nil
146
- #
147
- # start_calendar_interval <array_index=nil> <block of keys>
161
+ # Set or return the plist key "StartCalendarInterval"
162
+ #
148
163
  # This optional key causes the job to be started every calendar interval as specified. Missing arguments are considered to be wildcard. The semantics are much like
149
164
  # crontab(5). Unlike cron which skips job invocations when the computer is asleep, launchd will start the job the next time the computer wakes up. If multiple
150
165
  # intervals transpire before the computer is woken, those events will be coalesced into one event upon wake from sleep.
166
+ #
167
+ # @example Reference
168
+ # start_calendar_interval index=nil do
169
+ # minute <integer>
170
+ # # The minute on which this job will be run.
171
+ #
172
+ # hour <integer>
173
+ # # The hour on which this job will be run.
174
+ #
175
+ # day <integer>
176
+ # # The day on which this job will be run.
177
+ #
178
+ # weekday <integer>
179
+ # # The weekday on which this job will be run (0 and 7 are Sunday).
180
+ #
181
+ # month <integer>
182
+ # # The month on which this job will be run.
183
+ # end
184
+ #
185
+ # @example Example
186
+ # # Set start calendar interval
151
187
  #
152
- # start_calendar_interval index=nil do
153
- #
154
- # Minute <integer>
155
- # The minute on which this job will be run.
156
- #
157
- # Hour <integer>
158
- # The hour on which this job will be run.
159
- #
160
- # Day <integer>
161
- # The day on which this job will be run.
162
- #
163
- # Weekday <integer>
164
- # The weekday on which this job will be run (0 and 7 are Sunday).
165
- #
166
- # Month <integer>
167
- # The month on which this job will be run.
168
- #
169
- # end
188
+ # launchd_plist.start_calendar_interval 0 do
189
+ # hour 02
190
+ # minute 05
191
+ # day 06
192
+ # end
193
+ #
194
+ # launchd_plist.start_calendar_interval 1 do
195
+ # hour 10
196
+ # minute 30
197
+ # end
170
198
  #
171
- # Example:
199
+ # launchd_plist.start_calendar_interval do
200
+ # month 3
201
+ # end
172
202
  #
173
- # start_calendar_interval 0 do
174
- # hour 02
175
- # minute 05
176
- # day 06
177
- # end
203
+ # # Return start calendar interval
204
+ # launchd_plist.start_calendar_interval[1] => { "Hour" => 10, "Minute" => 30 }
205
+ # launchd_plist.start_calendar_interval.last => { "Month" => 3 }
178
206
  #
179
- # start_calendar_interval 1 do
180
- # hour 02
181
- # minute 05
182
- # day 06
183
- # end
207
+ # @param [Fixnum] index The array index for this calendar entry
208
+ # @param [Block] blk A block setting the specific start calendar intervals.
209
+ # Appends a new entry to the end of the array if no index specified.
184
210
  #
185
211
  def start_calendar_interval index=nil, &blk
186
212
  key = "StartCalendarInterval"
@@ -206,118 +232,130 @@ module Plist4r
206
232
  end
207
233
  end
208
234
 
209
- # :call-seq:
210
- # soft_resource_limits { block_of_keys }
211
- # soft_resource_limits -> hash or nil
212
- #
213
- # soft_resource_limits <block of keys>
214
- # Resource limits to be imposed on the job. These adjust variables set with setrlimit(2). The following keys apply:
215
- #
216
- # soft_resource_limits do
217
- #
218
- # Core <integer>
219
- # The largest size (in bytes) core file that may be created.
220
- #
221
- # CPU <integer>
222
- # The maximum amount of cpu time (in seconds) to be used by each process.
235
+ # Set or return the plist key "SoftResourceLimits"
223
236
  #
224
- # Data <integer>
225
- # The maximum size (in bytes) of the data segment for a process; this defines how far a program may extend its break with the sbrk(2) system call.
226
- #
227
- # FileSize <integer>
228
- # The largest size (in bytes) file that may be created.
229
- #
230
- # MemoryLock <integer>
231
- # The maximum size (in bytes) which a process may lock into memory using the mlock(2) function.
232
- #
233
- # NumberOfFiles <integer>
234
- # The maximum number of open files for this process. Setting this value in a system wide daemon will set the sysctl(3) kern.maxfiles (SoftResourceLimits) or
235
- # kern.maxfilesperproc (HardResourceLimits) value in addition to the setrlimit(2) values.
236
- #
237
- # NumberOfProcesses <integer>
238
- # The maximum number of simultaneous processes for this user id. Setting this value in a system wide daemon will set the sysctl(3) kern.maxproc (SoftResource-
239
- # Limits) or kern.maxprocperuid (HardResourceLimits) value in addition to the setrlimit(2) values.
240
- #
241
- # ResidentSetSize <integer>
242
- # The maximum size (in bytes) to which a process's resident set size may grow. This imposes a limit on the amount of physical memory to be given to a process;
243
- # if memory is tight, the system will prefer to take memory from processes that are exceeding their declared resident set size.
244
- #
245
- # Stack <integer>
246
- # The maximum size (in bytes) of the stack segment for a process; this defines how far a program's stack segment may be extended. Stack extension is performed
247
- # automatically by the system.
237
+ # Resource limits to be imposed on the job. These adjust variables set with setrlimit(2). The following keys apply:
248
238
  #
249
- # end
239
+ # @example Reference
240
+ # soft_resource_limits do
241
+ # core <integer>
242
+ # # The largest size (in bytes) core file that may be created.
243
+ #
244
+ # cpu <integer>
245
+ # # The maximum amount of cpu time (in seconds) to be used by each process.
246
+ #
247
+ # data <integer>
248
+ # # The maximum size (in bytes) of the data segment for a process; this defines how far a
249
+ # # program may extend its break with the sbrk(2) system call.
250
+ #
251
+ # file_size <integer>
252
+ # # The largest size (in bytes) file that may be created.
253
+ #
254
+ # memory_lock <integer>
255
+ # # The maximum size (in bytes) which a process may lock into memory using the mlock(2) function.
256
+ #
257
+ # number_of_files <integer>
258
+ # # The maximum number of open files for this process. Setting this value in a system wide
259
+ # # daemon will set the sysctl(3) kern.maxfiles (SoftResourceLimits) or kern.maxfilesperproc
260
+ # # (HardResourceLimits) value in addition to the setrlimit(2) values.
261
+ #
262
+ # number_of_processes <integer>
263
+ # # The maximum number of simultaneous processes for this user id. Setting this value in a
264
+ # # system wide daemon will set the sysctl(3) kern.maxproc (SoftResource-Limits) or
265
+ # # kern.maxprocperuid (HardResourceLimits) value in addition to the setrlimit(2) values.
266
+ #
267
+ # resident_set_size <integer>
268
+ # # The maximum size (in bytes) to which a process's resident set size may grow. This imposes
269
+ # # a limit on the amount of physical memory to be given to a process; if memory is tight, the
270
+ # # system will prefer to take memory from processes that are exceeding their declared resident
271
+ # # set size.
272
+ #
273
+ # stack <integer>
274
+ # # The maximum size (in bytes) of the stack segment for a process; this defines how far a
275
+ # # program's stack segment may be extended. Stack extension is performed automatically
276
+ # # by the system.
277
+ # end
250
278
  #
251
- # Example:
279
+ # @example Example
280
+ #
281
+ # # Set soft resource limits
282
+ # soft_resource_limits do
283
+ # NumberOfProcesses 4
284
+ # NumberOfFiles 512
285
+ # end
252
286
  #
253
- # soft_resource_limits do
254
- # NumberOfProcesses 4
255
- # NumberOfFiles 512
256
- # end
287
+ # # Return soft resource limits
288
+ # soft_resource_limits => { "NumberOfProcesses" => 4, "NumberOfFiles" => 512 }
257
289
  #
258
290
  def soft_resource_limits value=nil, &blk
259
291
  key = "SoftResourceLimits"
260
292
  if blk
261
- @hash[key] ||= ::ActiveSupport::OrderedHash.new
293
+ @hash[key] ||= ::Plist4r::OrderedHash.new
262
294
  @hash[key] = ::LaunchdPlistStructs::ResourceLimits.new(@hash[key],&blk).hash
263
295
  else
264
296
  @hash[key]
265
297
  end
266
298
  end
267
299
 
268
- # :call-seq:
269
- # hard_resource_limits { block_of_keys }
270
- # hard_resource_limits -> hash or nil
271
- #
272
- # hard_resource_limits <block of keys>
273
- # Resource limits to be imposed on the job. These adjust variables set with setrlimit(2). The following keys apply:
274
- #
275
- # hard_resource_limits do
276
- #
277
- # Core <integer>
278
- # The largest size (in bytes) core file that may be created.
279
- #
280
- # CPU <integer>
281
- # The maximum amount of cpu time (in seconds) to be used by each process.
300
+ # Set or return the plist key "HardResourceLimits"
282
301
  #
283
- # Data <integer>
284
- # The maximum size (in bytes) of the data segment for a process; this defines how far a program may extend its break with the sbrk(2) system call.
285
- #
286
- # FileSize <integer>
287
- # The largest size (in bytes) file that may be created.
288
- #
289
- # MemoryLock <integer>
290
- # The maximum size (in bytes) which a process may lock into memory using the mlock(2) function.
291
- #
292
- # NumberOfFiles <integer>
293
- # The maximum number of open files for this process. Setting this value in a system wide daemon will set the sysctl(3) kern.maxfiles (SoftResourceLimits) or
294
- # kern.maxfilesperproc (HardResourceLimits) value in addition to the setrlimit(2) values.
295
- #
296
- # NumberOfProcesses <integer>
297
- # The maximum number of simultaneous processes for this user id. Setting this value in a system wide daemon will set the sysctl(3) kern.maxproc (SoftResource-
298
- # Limits) or kern.maxprocperuid (HardResourceLimits) value in addition to the setrlimit(2) values.
299
- #
300
- # ResidentSetSize <integer>
301
- # The maximum size (in bytes) to which a process's resident set size may grow. This imposes a limit on the amount of physical memory to be given to a process;
302
- # if memory is tight, the system will prefer to take memory from processes that are exceeding their declared resident set size.
303
- #
304
- # Stack <integer>
305
- # The maximum size (in bytes) of the stack segment for a process; this defines how far a program's stack segment may be extended. Stack extension is performed
306
- # automatically by the system.
307
- #
308
- # end
302
+ # Resource limits to be imposed on the job. These adjust variables set with setrlimit(2). The following keys apply:
309
303
  #
310
- # Example:
304
+ # @example Reference
305
+ # hard_resource_limits do
306
+ # core <integer>
307
+ # # The largest size (in bytes) core file that may be created.
308
+ #
309
+ # cpu <integer>
310
+ # # The maximum amount of cpu time (in seconds) to be used by each process.
311
+ #
312
+ # data <integer>
313
+ # # The maximum size (in bytes) of the data segment for a process; this defines how far a
314
+ # # program may extend its break with the sbrk(2) system call.
315
+ #
316
+ # file_size <integer>
317
+ # # The largest size (in bytes) file that may be created.
318
+ #
319
+ # memory_lock <integer>
320
+ # # The maximum size (in bytes) which a process may lock into memory using the mlock(2) function.
321
+ #
322
+ # number_of_files <integer>
323
+ # # The maximum number of open files for this process. Setting this value in a system wide
324
+ # # daemon will set the sysctl(3) kern.maxfiles (SoftResourceLimits) or kern.maxfilesperproc
325
+ # # (HardResourceLimits) value in addition to the setrlimit(2) values.
326
+ #
327
+ # number_of_processes <integer>
328
+ # # The maximum number of simultaneous processes for this user id. Setting this value in a
329
+ # # system wide daemon will set the sysctl(3) kern.maxproc (SoftResource-Limits) or
330
+ # # kern.maxprocperuid (HardResourceLimits) value in addition to the setrlimit(2) values.
331
+ #
332
+ # resident_set_size <integer>
333
+ # # The maximum size (in bytes) to which a process's resident set size may grow. This imposes
334
+ # # a limit on the amount of physical memory to be given to a process; if memory is tight, the
335
+ # # system will prefer to take memory from processes that are exceeding their declared resident
336
+ # # set size.
337
+ #
338
+ # stack <integer>
339
+ # # The maximum size (in bytes) of the stack segment for a process; this defines how far a
340
+ # # program's stack segment may be extended. Stack extension is performed automatically
341
+ # # by the system.
342
+ # end
311
343
  #
312
- # hard_resource_limits do
313
- # NumberOfProcesses 4
314
- # NumberOfFiles 512
315
- # end
344
+ # @example Example
345
+ #
346
+ # # Set hard resource limits
347
+ # hard_resource_limits do
348
+ # NumberOfProcesses 4
349
+ # NumberOfFiles 512
350
+ # end
316
351
  #
352
+ # # Return hard resource limits
353
+ # hard_resource_limits => { "NumberOfProcesses" => 4, "NumberOfFiles" => 512 }
354
+ #
317
355
  def hard_resource_limits value=nil, &blk
318
356
  key = "HardResourceLimits"
319
357
  if blk
320
- @hash[key] ||= ::ActiveSupport::OrderedHash.new
358
+ @hash[key] ||= ::Plist4r::OrderedHash.new
321
359
  @hash[key] = ::LaunchdPlistStructs::ResourceLimits.new(@hash[key],&blk).hash
322
360
  else
323
361
  @hash[key]
@@ -336,7 +374,7 @@ module Plist4r
336
374
  @hash[service] = value
337
375
  set_or_return :bool, service, value
338
376
  elsif blk
339
- @hash[service] = ::ActiveSupport::OrderedHash.new
377
+ @hash[service] = ::Plist4r::OrderedHash.new
340
378
  @hash[service] = ::LaunchdPlistStructs::MachServices::MachService.new(@hash[service],&blk).hash
341
379
  else
342
380
  @orig
@@ -344,42 +382,49 @@ module Plist4r
344
382
  end
345
383
  end
346
384
 
347
- # :call-seq:
348
- # mach_services { block }
349
- # mach_services -> hash or nil
385
+ # Set or return the plist key "MachServices"
350
386
  #
351
- # mach_services <dictionary of booleans or a dictionary of dictionaries>
387
+ # Structure: "A dictionary of booleans" or a "dictionary of dictionaries"
388
+ #
352
389
  # This optional key is used to specify Mach services to be registered with the Mach bootstrap sub-system. Each key in this dictionary should be the name of service
353
390
  # to be advertised. The value of the key must be a boolean and set to true. Alternatively, a dictionary can be used instead of a simple true value.
354
391
  #
355
- # ResetAtClose <boolean>
356
- # If this boolean is false, the port is recycled, thus leaving clients to remain oblivious to the demand nature of job. If the value is set to true, clients
357
- # receive port death notifications when the job lets go of the receive right. The port will be recreated atomically with respect to bootstrap_look_up() calls,
358
- # so that clients can trust that after receiving a port death notification, the new port will have already been recreated. Setting the value to true should be
359
- # done with care. Not all clients may be able to handle this behavior. The default value is false.
360
- #
361
- # HideUntilCheckIn <boolean>
362
- # Reserve the name in the namespace, but cause bootstrap_look_up() to fail until the job has checked in with launchd.
363
- #
364
392
  # Finally, for the job itself, the values will be replaced with Mach ports at the time of check-in with launchd.
365
393
  #
366
- # Example:
394
+ # @example Reference
395
+ # mach_services do
396
+ # reset_at_close <boolean>
397
+ # # If this boolean is false, the port is recycled, thus leaving clients to remain oblivious
398
+ # # to the demand nature of job. If the value is set to true, clients receive port death
399
+ # # notifications when the job lets go of the receive right. The port will be recreated
400
+ # # atomically with respect to bootstrap_look_up() calls, so that clients can trust that
401
+ # # after receiving a port death notification, the new port will have already been recreated.
402
+ # # Setting the value to true should be done with care. Not all clients may be able to handle
403
+ # # this behavior. The default value is false.
404
+ #
405
+ # hide_until_check_in <boolean>
406
+ # # Reserve the name in the namespace, but cause bootstrap_look_up() to fail until the job
407
+ # # has checked in with launchd.
408
+ # end
367
409
  #
368
- # mach_services do
369
- # add "com.apple.afpfs_checkafp", true
370
- # end
410
+ # @example Example
371
411
  #
372
- # mach_services do
373
- # add "com.apple.AppleFileServer" do
374
- # hide_until_check_in true
375
- # reset_at_close false
376
- # end
377
- # end
412
+ # # Set mach services
413
+ # mach_services do
414
+ # add "com.apple.afpfs_checkafp", true
415
+ # end
416
+ #
417
+ # mach_services do
418
+ # add "com.apple.AppleFileServer" do
419
+ # hide_until_check_in true
420
+ # reset_at_close false
421
+ # end
422
+ # end
378
423
  #
379
424
  def mach_services value=nil, &blk
380
425
  key = "MachServices"
381
426
  if blk
382
- @hash[key] ||= ::ActiveSupport::OrderedHash.new
427
+ @hash[key] ||= ::Plist4r::OrderedHash.new
383
428
  @hash[key] = ::LaunchdPlistStructs::MachServices.new(@hash[key],&blk).hash
384
429
  else
385
430
  @hash[key]
@@ -425,122 +470,191 @@ module Plist4r
425
470
  end
426
471
  end
427
472
 
428
- # :call-seq:
429
- # sockets(socket_key="Listeners") { block_of_keys }
430
- # sockets(socket_key="Listeners", socket_index) { block_of_keys }
431
- # sockets -> hash or nil
432
- #
433
- # socket <array_index=nil> <block of keys>
434
- # socket <dictionary... OR dictionary + array index...>
473
+ # Set or return the plist key "Sockets"
435
474
  #
436
- # Please See: http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/LaunchOnDemandDaemons.html
437
- # for more information about how to properly use the Sockets feature
475
+ # Structure: "dictionary of dictionaries... OR dictionary of array of dictionaries..."
438
476
  #
439
- # This optional key is used to specify launch on demand sockets that can be used to let launchd know when to run the job. The job must check-in to get a copy of the
440
- # file descriptors using APIs outlined in launch(3). The keys of the top level Sockets dictionary can be anything. They are meant for the application developer to
441
- # use to differentiate which descriptors correspond to which application level protocols (e.g. http vs. ftp vs. DNS...). At check-in time, the value of each Sockets
442
- # dictionary key will be an array of descriptors. Daemon/Agent writers should consider all descriptors of a given key to be to be effectively equivalent, even though
443
- # each file descriptor likely represents a different networking protocol which conforms to the criteria specified in the job configuration file.
444
- # The parameters below are used as inputs to call getaddrinfo(3).
477
+ # Please see http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/LaunchOnDemandDaemons.html
478
+ # for more information about how to properly use the Sockets feature.
445
479
  #
446
- # socket "socket_key" do
480
+ # NOTE:
447
481
  #
448
- # SockType <string>
449
- # This optional key tells launchctl what type of socket to create. The default is "stream" and other valid values for this key are "dgram" and "seqpacket"
450
- # respectively.
482
+ # Sockets will work only if a special Sockets callback method is implemented within the daemon which
483
+ # launchd is attempting to start. (this is not commonly the case for most OSS eg apache, mysql, etc).
484
+ # If writing / modifying a deamon is not an option, it may be more worthwhile to consider if the
485
+ # Launchd WatchPaths feature is applicable instead of Sockets.
451
486
  #
452
- # SockPassive <boolean>
453
- # This optional key specifies whether listen(2) or connect(2) should be called on the created file descriptor. The default is true ("to listen").
487
+ # Heres 2 example deamons which implement the necessary sockets callbacks.
454
488
  #
455
- # SockNodeName <string>
456
- # This optional key specifies the node to connect(2) or bind(2) to.
489
+ # Examples:
457
490
  #
458
- # SockServiceName <string>
459
- # This optional key specifies the service on the node to connect(2) or bind(2) to.
491
+ # http://developer.apple.com/mac/library/samplecode/BetterAuthorizationSample/Introduction/Intro.html
460
492
  #
461
- # SockFamily <string>
462
- # This optional key can be used to specifically request that "IPv4" or "IPv6" socket(s) be created.
493
+ # http://bitbucket.org/mikemccracken/py-launchd/wiki/Home
463
494
  #
464
- # SockProtocol <string>
465
- # This optional key specifies the protocol to be passed to socket(2). The only value understood by this key at the moment is "TCP".
495
+ # The remainder of this section simply describes how to declare Sockets definitions within a launchd plist file.
496
+ # It does not explain how to implement the sockets feature in a deamon. (For that, please see the above links)
466
497
  #
467
- # SockPathName <string>
468
- # This optional key implies SockFamily is set to "Unix". It specifies the path to connect(2) or bind(2) to.
498
+ # This optional key is used to specify launch on demand sockets that can be used to let launchd know when to run the job. The job must check-in to get a copy of the
499
+ # file descriptors using APIs outlined in launch(3). The keys of the top level Sockets dictionary can be anything. They are meant for the application developer to
500
+ # use to differentiate which descriptors correspond to which application level protocols (e.g. http vs. ftp vs. DNS...). At check-in time, the value of each Sockets
501
+ # dictionary key will be an array of descriptors. Daemon/Agent writers should consider all descriptors of a given key to be to be effectively equivalent, even though
502
+ # each file descriptor likely represents a different networking protocol which conforms to the criteria specified in the job configuration file.
503
+ # The parameters below are used as inputs to call getaddrinfo(3).
469
504
  #
470
- # SecureSocketWithKey <string>
471
- # This optional key is a variant of SockPathName. Instead of binding to a known path, a securely generated socket is created and the path is assigned to the
472
- # environment variable that is inherited by all jobs spawned by launchd.
505
+ # @example Reference
506
+ # socket "socket_key" do
507
+ # sock_type <string>
508
+ # # This optional key tells launchctl what type of socket to create. The default is "stream"
509
+ # # and other valid values for this key are "dgram" and "seqpacket" respectively.
510
+ #
511
+ # sock_passive <boolean>
512
+ # # This optional key specifies whether listen(2) or connect(2) should be called on the
513
+ # # created file descriptor. The default is true ("to listen").
514
+ #
515
+ # sock_node_name <string>
516
+ # # This optional key specifies the node to connect(2) or bind(2) to.
517
+ #
518
+ # sock_service_name <string>
519
+ # # This optional key specifies the service on the node to connect(2) or bind(2) to.
520
+ #
521
+ # sock_family <string>
522
+ # # This optional key can be used to specifically request that "IPv4" or "IPv6" socket(s) be
523
+ # # created.
524
+ #
525
+ # sock_protocol <string>
526
+ # # This optional key specifies the protocol to be passed to socket(2). The only value
527
+ # # understood by this key at the moment is "TCP".
528
+ #
529
+ # sock_path_name <string>
530
+ # # This optional key implies SockFamily is set to "Unix". It specifies the path to
531
+ # # connect(2) or bind(2) to.
532
+ #
533
+ # secure_socket_with_key <string>
534
+ # # This optional key is a variant of SockPathName. Instead of binding to a known path,
535
+ # # a securely generated socket is created and the path is assigned to the environment
536
+ # # variable that is inherited by all jobs spawned by launchd.
537
+ #
538
+ # sock_path_mode <integer>
539
+ # # This optional key specifies the mode of the socket. Known bug: Property lists don't
540
+ # # support octal, so please convert the value to decimal.
541
+ #
542
+ # bonjour <boolean or string or array of strings>
543
+ # # This optional key can be used to request that the service be registered with the
544
+ # # mDNSResponder(8). If the value is boolean, the service name is inferred from
545
+ # # the SockServiceName.
546
+ #
547
+ # multicast_group <string>
548
+ # # This optional key can be used to request that the datagram socket join a multicast
549
+ # # group. If the value is a hostname, then getaddrinfo(3) will be used to join the
550
+ # # correct multicast address for a given socket family. If an explicit IPv4 or IPv6
551
+ # # address is given, it is required that the SockFamily family also be set, otherwise
552
+ # # the results are undefined.
553
+ # end
473
554
  #
474
- # SockPathMode <integer>
475
- # This optional key specifies the mode of the socket. Known bug: Property lists don't support octal, so please convert the value to decimal.
555
+ # @example Example
476
556
  #
477
- # Bonjour <boolean or string or array of strings>
478
- # This optional key can be used to request that the service be registered with the mDNSResponder(8). If the value is boolean, the service name is inferred from
479
- # the SockServiceName.
557
+ # # Method construct
558
+ # socket(socket_key="Listeners") { block_of_keys }
559
+ # socket(socket_key="Listeners", socket_index) { block_of_keys }
560
+ # socket -> hash or nil
480
561
  #
481
- # MulticastGroup <string>
482
- # This optional key can be used to request that the datagram socket join a multicast group. If the value is a hostname, then getaddrinfo(3) will be used to
483
- # join the correct multicast address for a given socket family. If an explicit IPv4 or IPv6 address is given, it is required that the SockFamily family also be
484
- # set, otherwise the results are undefined.
562
+ # # Write this socket to index [0]. Creates an *array* of sockets
563
+ # # This array is held within the default sockets key name, "Listeners"
564
+ # launchd_plist.socket 0 do
565
+ # sock_service_name "netbios-ssn"
566
+ # end
567
+ #
568
+ # # Add a new socket called "netbios". Creates a *dictionary* of sockets
569
+ # launchd_plist.socket "netbios" do
570
+ # sock_service_name "netbios"
571
+ # bonjour ['smb']
572
+ # end
485
573
  #
486
- # end
574
+ # # Inspect all the sockets structure afterward (recommended)
575
+ # puts launchd_plist.socket.inspect
487
576
  #
488
- # NOTE:
489
- # Sockets is a complex structure. If you are manupilating an existing Sockets entry, then you must fully specify the key you want to modify.
490
- # so `socket do` should be written as `socket "Listeners" do`, (and in the case of an array of sockets) `socket 0 do` should be written as `socket "Listeners" 0 do`
577
+ # @example Correct Usage, and Erroneous usage
491
578
  #
492
- # Examples:
579
+ # # scenario 1:
580
+ # socket do
581
+ # sock_service_name "netbios-ssn"
582
+ # end
583
+ # # => Result: Ok. The default "Listeners" toplevel key is generated implicitly.
584
+ #
585
+ # # scenario 2:
586
+ # socket do
587
+ # sock_service_name "netbios-ssn"
588
+ # end
589
+ # socket do
590
+ # sock_service_name "netbios"
591
+ # bonjour ['smb']
592
+ # end
593
+ # # => Result: Exception error is raise the second time because the "Listeners" key already
594
+ # # exists. We can forcefully overwrite this existing sockets key with `socket "Listeners" do`.
595
+ #
596
+ # # scenario 3:
597
+ # socket "netbios-ssn" do
598
+ # sock_service_name "netbios-ssn"
599
+ # end
600
+ # socket "netbios" do
601
+ # sock_service_name "netbios"
602
+ # bonjour ['smb']
603
+ # end
604
+ # => Result: Ok. Each Sockets entry has a unique key.
605
+ #
606
+ # # scenario 4:
607
+ # socket 0 do
608
+ # sock_service_name "netbios-ssn"
609
+ # end
610
+ # socket 1 do
611
+ # sock_service_name "netbios"
612
+ # bonjour ['smb']
613
+ # end
614
+ # # => Result: Ok. Each Sockets entry has a unique array index. The array of all these sockets
615
+ # # is held within the default "Listeners" key (implicit array or sockets).
616
+ #
617
+ # # scenario 5:
618
+ # socket do
619
+ # sock_service_name "netbios-ssn"
620
+ # end
621
+ # socket[0] do
622
+ # sock_service_name "netbios"
623
+ # bonjour ['smb']
624
+ # end
625
+ # # => Result: Exception error. because we cant mix and match types with the implicit
626
+ # # "Listeners" key. If in doubt then avoid using the arrays.
493
627
  #
494
- # # scenario 1:
495
- # socket do
496
- # sock_service_name "netbios-ssn"
497
- # end
498
- # # => Result: Ok. The default "Listeners" toplevel key is generated implicitly.
628
+ # @example NOTE: Accessing the default sockets
499
629
  #
500
- # # scenario 2:
501
- # socket do
502
- # sock_service_name "netbios-ssn"
503
- # end
630
+ # # Sockets is a complex structure. When manupilating an existing Sockets entry, (the second
631
+ # # time around), we must fully specify the key to modify. This is usually achieved simply
632
+ # # specifying the implicit "Listeners" key name.
633
+ #
634
+ # # For example, if we created a socket with
504
635
  # socket do
505
- # sock_service_name "netbios"
506
- # bonjour ['smb']
636
+ # # ...
507
637
  # end
508
- # # => Result: Exception error is raise the second time because the "Listeners" key already exists. We can forcefully overwrite this existing sockets key with `socket "Listeners" do`.
509
638
  #
510
- # # scenario 3:
511
- # socket "netbios-ssn" do
512
- # sock_service_name "netbios-ssn"
513
- # end
514
- # socket "netbios" do
515
- # sock_service_name "netbios"
516
- # bonjour ['smb']
639
+ # # is accessed as
640
+ # socket "Listeners" do
641
+ # # ...
517
642
  # end
518
- # => Result: Ok. Each Sockets entry has a unique key.
519
643
  #
520
- # # scenario 4:
644
+ # # or if an array of sockets
521
645
  # socket 0 do
522
- # sock_service_name "netbios-ssn"
523
- # end
524
- # socket 1 do
525
- # sock_service_name "netbios"
526
- # bonjour ['smb']
646
+ # # ...
527
647
  # end
528
- # # => Result: Ok. Each Sockets entry has a unique array index. The array of all these sockets is held within the default "Listeners" key (implicit array or sockets).
529
- #
530
- # # scenario 5:
531
- # socket do
532
- # sock_service_name "netbios-ssn"
533
- # end
534
- # socket[0] do
535
- # sock_service_name "netbios"
536
- # bonjour ['smb']
648
+ #
649
+ # # in reality becomes
650
+ # socket "Listeners" 0 do
651
+ # # ...
537
652
  # end
538
- # # => Result: Exception error. because we cant mix and match types with the implicit "Listeners" key. If in doubt then avoid using the arrays.
539
653
  #
540
654
  def socket index_or_key=nil, index=nil, &blk
541
655
  key = "Sockets"
542
656
  if blk
543
- @hash[key] ||= ::ActiveSupport::OrderedHash.new
657
+ @hash[key] ||= ::Plist4r::OrderedHash.new
544
658
  sockets = ::LaunchdPlistStructs::Sockets.new(@hash[key]).hash
545
659
 
546
660
  case index_or_key