launchy 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,25 +1,32 @@
1
- == Changes
2
- === Version 0.3.2 - 2008-05-21
1
+ = Launchy Changlog
2
+
3
+ == Version 0.3.3 - 2009-02-19
4
+
5
+ * pass command line as discrete items to system() to avoid string
6
+ interpretation by the system shell. (Suraj N. Kurapati)
7
+ * rework project layout and tasks
8
+
9
+ == Version 0.3.2 - 2008-05-21
3
10
 
4
11
  * detect aix and mingw as known operating systems.
5
12
 
6
- === Version 0.3.1 - 2007-09-08
13
+ == Version 0.3.1 - 2007-09-08
7
14
 
8
15
  * finalize the command line wrapper around the launchy library.
9
16
  * added more tests
10
17
 
11
- === Version 0.3.0 - 2007-08-30
18
+ == Version 0.3.0 - 2007-08-30
12
19
 
13
20
  * reorganize the code structure, removing Spawnable namespace
14
21
  * removed 'do_magic' method, changed it to 'open'
15
22
  * added override environment variable LAUNCHY_HOST_OS for testing
16
23
  * fix broken cygwin support [Bug #13472]
17
24
 
18
- === Version 0.2.1 - 2007-08-18
25
+ == Version 0.2.1 - 2007-08-18
19
26
 
20
27
  * fix inability to find windows executables [Bug #13132]
21
28
 
22
- === Version 0.2.0 - 2007-08-11
29
+ == Version 0.2.0 - 2007-08-11
23
30
 
24
31
  * rework browser finding
25
32
  * manual override with LAUNCHY_BROWSER environment variable
@@ -28,23 +35,23 @@
28
35
  * removed win32 gem
29
36
  * Add debug output by setting LAUNCHY_DEBUG environment variable to 'true'
30
37
 
31
- === Version 0.1.2 - 2007-08-11
38
+ == Version 0.1.2 - 2007-08-11
32
39
 
33
40
  * forked child exits without calling at_exit handlers
34
41
 
35
- === Version 0.1.1
42
+ == Version 0.1.1
36
43
 
37
44
  * fixed rubyforge task to release mswin32 gem also
38
45
 
39
- === Version 0.1.0
46
+ == Version 0.1.0
40
47
 
41
48
  * Initial public release
42
49
  * switched to using fork to spawn process and require 'win32/process' if on windows
43
50
 
44
- === Version 0.0.2
51
+ == Version 0.0.2
45
52
 
46
53
  * First attempt at using systemu to spawn processes
47
54
 
48
- === Version 0.0.1
55
+ == Version 0.0.1
49
56
 
50
57
  * Initially working release
data/README CHANGED
@@ -7,11 +7,11 @@
7
7
  == DESCRIPTION
8
8
 
9
9
  Launchy is helper class for launching cross-platform applications in a
10
- fire and forget manner.
10
+ fire and forget manner.
11
11
 
12
- There are application concepts (browser, email client, etc) that are common
13
- across all platforms, and they may be launched differently on each
14
- platform. Launchy is here to make a common approach to launching
12
+ There are application concepts (browser, email client, etc) that are
13
+ common across all platforms, and they may be launched differently on
14
+ each platform. Launchy is here to make a common approach to launching
15
15
  external application from within ruby programs.
16
16
 
17
17
  == FEATURES
@@ -32,36 +32,18 @@ OR
32
32
 
33
33
  Launchy::Browser.new.visit("http://www.ruby-lang.org/")
34
34
 
35
- == LICENSE
36
-
37
- Copyright (c) 2007, Jeremy Hinegardner
38
-
39
- All rights reserved.
40
-
41
- Redistribution and use in source and binary forms, with or without
42
- modification, are permitted provided that the following conditions are met:
43
-
44
- * Redistributions of source code must retain the above copyright notice,
45
- this list of conditions and the following disclaimer.
46
-
47
- * Redistributions in binary form must reproduce the above copyright notice,
48
- this list of conditions and the following disclaimer in the
49
- documentation and/or other materials provided with the
50
- distribution.
51
-
52
- * Neither the name of Jeremy Hinegardner nor the
53
- names of its contributors may be used to endorse or promote
54
- products derived from this software without specific prior written
55
- permission.
56
-
57
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
58
- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
59
- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
60
- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
61
- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
62
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
63
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
64
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
65
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
66
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
67
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
+ == ISC LICENSE
36
+
37
+ Copyright (c) 2007-2009 Jeremy Hinegardner
38
+
39
+ Permission to use, copy, modify, and/or distribute this software for any
40
+ purpose with or without fee is hereby granted, provided that the above
41
+ copyright notice and this permission notice appear in all copies.
42
+
43
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
44
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
45
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
46
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
47
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
48
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
49
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,62 @@
1
+ #--
2
+ # Copyright (c) 2007 Jeremy Hinegardner
3
+ # All rights reserved. See LICENSE and/or COPYING for details.
4
+ #++
5
+
6
+ #-------------------------------------------------------------------------------
7
+ # make sure our project's top level directory and the lib directory are added to
8
+ # the ruby search path.
9
+ #-------------------------------------------------------------------------------
10
+ $: << File.expand_path(File.join(File.dirname(__FILE__),"lib"))
11
+ $: << File.expand_path(File.dirname(__FILE__))
12
+
13
+
14
+ #-------------------------------------------------------------------------------
15
+ # load the global project configuration and add in the top level clean and
16
+ # clobber tasks so that other tasks can utilize those constants if necessary
17
+ # This loads up the defaults for the whole project configuration
18
+ #-------------------------------------------------------------------------------
19
+ require 'rubygems'
20
+ require 'tasks/config.rb'
21
+ require 'rake/clean'
22
+
23
+ #-------------------------------------------------------------------------------
24
+ # Main configuration for the project, these overwrite the items that are in
25
+ # tasks/config.rb
26
+ #-------------------------------------------------------------------------------
27
+ require 'launchy/version'
28
+ require 'launchy/paths'
29
+
30
+ Configuration.for("project") {
31
+ name "launchy"
32
+ version Launchy::VERSION
33
+ author "Jeremy Hinegardner"
34
+ email "jeremy@copiousfreetime.org"
35
+ homepage "http://copiousfreetime.rubyforge.org/launchy/"
36
+ }
37
+
38
+ #-------------------------------------------------------------------------------
39
+ # load up all the project tasks and setup the default task to be the
40
+ # test:default task.
41
+ #-------------------------------------------------------------------------------
42
+ Configuration.for("packaging").files.tasks.each do |tasklib|
43
+ import tasklib
44
+ end
45
+ task :default => 'test:default'
46
+
47
+ #-------------------------------------------------------------------------------
48
+ # Finalize the loading of all pending imports and update the top level clobber
49
+ # task to depend on all possible sub-level tasks that have a name like
50
+ # ':clobber' in other namespaces. This allows us to say:
51
+ #
52
+ # rake clobber
53
+ #
54
+ # and it will get everything.
55
+ #-------------------------------------------------------------------------------
56
+ Rake.application.load_imports
57
+ Rake.application.tasks.each do |t|
58
+ if t.name =~ /:clobber/ then
59
+ task :clobber => [t.name]
60
+ end
61
+ end
62
+
File without changes
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'launchy/version'
3
+ require 'tasks/config'
4
+
5
+ Launchy::GEM_SPEC = Gem::Specification.new do |spec|
6
+ proj = Configuration.for('project')
7
+ spec.name = proj.name
8
+ spec.version = Launchy::VERSION
9
+
10
+ spec.author = proj.author
11
+ spec.email = proj.email
12
+ spec.homepage = proj.homepage
13
+ spec.summary = proj.summary
14
+ spec.description = proj.description
15
+ spec.platform = Gem::Platform::RUBY
16
+
17
+
18
+ pkg = Configuration.for('packaging')
19
+ spec.files = pkg.files.all
20
+ spec.executables = pkg.files.bin.collect { |b| File.basename(b) }
21
+
22
+ # add dependencies here
23
+ spec.add_dependency("rake", ">= 0.8.1")
24
+ spec.add_dependency("configuration", ">= 0.0.5")
25
+
26
+ if rdoc = Configuration.for_if_exist?('rdoc') then
27
+ spec.has_rdoc = true
28
+ spec.extra_rdoc_files = pkg.files.rdoc
29
+ spec.rdoc_options = rdoc.options + [ "--main" , rdoc.main_page ]
30
+ else
31
+ spec.has_rdoc = false
32
+ end
33
+
34
+ if test = Configuration.for_if_exist?('testing') then
35
+ spec.test_files = test.files
36
+ end
37
+
38
+ if rf = Configuration.for_if_exist?('rubyforge') then
39
+ spec.rubyforge_project = rf.project
40
+ end
41
+ end
@@ -1,58 +1,53 @@
1
1
  module Launchy
2
-
3
- ROOT_DIR = File.expand_path(File.join(File.dirname(__FILE__),".."))
4
- LIB_DIR = File.join(ROOT_DIR,"lib").freeze
5
- RESOURCE_DIR = File.join(ROOT_DIR,"resources").freeze
6
-
7
- #
8
- # Utility method to require all files ending in .rb in the directory
9
- # with the same name as this file minus .rb
2
+ #
3
+ # Utility method to require all files ending in .rb in the directory
4
+ # with the same name as this file minus .rb
5
+ #
6
+ def self.require_all_libs_relative_to(fname)
7
+ prepend = File.basename(fname,".rb")
8
+ search_me = File.join(File.dirname(fname),prepend)
9
+
10
+ Dir.entries(search_me).each do |rb|
11
+ if File.extname(rb) == ".rb" then
12
+ require "#{prepend}/#{File.basename(rb,".rb")}"
13
+ end
14
+ end
15
+ end
16
+
17
+ class << self
10
18
  #
11
- def require_all_libs_relative_to(fname)
12
- prepend = File.basename(fname,".rb")
13
- search_me = File.join(File.dirname(fname),prepend)
14
-
15
- Dir.entries(search_me).each do |rb|
16
- if File.extname(rb) == ".rb" then
17
- require "#{prepend}/#{File.basename(rb,".rb")}"
18
- end
19
- end
20
- end
21
- module_function :require_all_libs_relative_to
22
-
23
- class << self
24
- def open(*params)
25
- begin
26
- klass = Launchy::Application.find_application_class_for(*params)
27
- if klass then
28
- klass.run(*params)
29
- else
30
- msg = "Unable to launch #{params.join(' ')}"
31
- Launchy.log "#{self.name} : #{msg}"
32
- $stderr.puts msg
33
- end
34
- rescue Exception => e
35
- msg = "Failure in opening #{params.join(' ')} : #{e}"
36
- Launchy.log "#{self.name} : #{msg}"
37
- $stderr.puts msg
38
- end
39
- end
40
-
41
- # Setting the LAUNCHY_DEBUG environment variable to 'true' will spew
42
- # debug information to $stderr
43
- def log(msg)
44
- if ENV['LAUNCHY_DEBUG'] == 'true' then
45
- $stderr.puts "LAUNCHY_DEBUG: #{msg}"
46
- end
47
- end
48
-
49
- # Create an instance of the commandline application of launchy
50
- def command_line
51
- Launchy::CommandLine.new
19
+ # Convenience method to launch an item
20
+ #
21
+ def open(*params)
22
+ begin
23
+ klass = Launchy::Application.find_application_class_for(*params)
24
+ if klass then
25
+ klass.run(*params)
26
+ else
27
+ msg = "Unable to launch #{params.join(' ')}"
28
+ Launchy.log "#{self.name} : #{msg}"
29
+ $stderr.puts msg
52
30
  end
31
+ rescue Exception => e
32
+ msg = "Failure in opening #{params.join(' ')} : #{e}"
33
+ Launchy.log "#{self.name} : #{msg}"
34
+ $stderr.puts msg
35
+ end
36
+ end
37
+
38
+ # Setting the LAUNCHY_DEBUG environment variable to 'true' will spew
39
+ # debug information to $stderr
40
+ def log(msg)
41
+ if ENV['LAUNCHY_DEBUG'] == 'true' then
42
+ $stderr.puts "LAUNCHY_DEBUG: #{msg}"
43
+ end
44
+ end
45
+
46
+ # Create an instance of the commandline application of launchy
47
+ def command_line
48
+ Launchy::CommandLine.new
53
49
  end
54
-
55
-
50
+ end
56
51
  end
57
52
 
58
53
  Launchy.require_all_libs_relative_to(__FILE__)
@@ -1,163 +1,174 @@
1
1
  require 'rbconfig'
2
2
 
3
3
  module Launchy
4
- class Application
5
-
6
- KNOWN_OS_FAMILIES = [ :windows, :darwin, :nix, :cygwin ]
7
-
8
- class << self
9
- def inherited(sub_class)
10
- application_classes << sub_class
11
- end
12
- def application_classes
13
- @application_classes ||= []
14
- end
15
-
16
- def find_application_class_for(*args)
17
- Launchy.log "#{self.name} : finding application classes for [#{args.join(' ')}]"
18
- application_classes.find do |klass|
19
- Launchy.log "#{self.name} : Trying #{klass.name}"
20
- if klass.handle?(*args) then
21
- true
22
- else
23
- false
24
- end
25
- end
26
- end
27
-
28
- # find an executable in the available paths
29
- # mkrf did such a good job on this I had to borrow it.
30
- def find_executable(bin,*paths)
31
- paths = ENV['PATH'].split(File::PATH_SEPARATOR) if paths.empty?
32
- paths.each do |path|
33
- file = File.join(path,bin)
34
- if File.executable?(file) then
35
- Launchy.log "#{self.name} : found executable #{file}"
36
- return file
37
- end
38
- end
39
- Launchy.log "#{self.name} : Unable to find `#{bin}' in #{paths.join(', ')}"
40
- return nil
41
- end
42
-
43
- # return the current 'host_os' string from ruby's configuration
44
- def my_os
45
- if ENV['LAUNCHY_HOST_OS'] then
46
- Launchy.log "#{self.name} : Using LAUNCHY_HOST_OS override of '#{ENV['LAUNCHY_HOST_OS']}'"
47
- return ENV['LAUNCHY_HOST_OS']
48
- else
49
- ::Config::CONFIG['host_os']
50
- end
51
- end
52
-
53
- # detect what the current os is and return :windows, :darwin or :nix
54
- def my_os_family(test_os = my_os)
55
- case test_os
56
- when /mingw/i
57
- family = :windows
58
- when /mswin/i
59
- family = :windows
60
- when /windows/i
61
- family = :windows
62
- when /darwin/i
63
- family = :darwin
64
- when /mac os/i
65
- family = :darwin
66
- when /solaris/i
67
- family = :nix
68
- when /bsd/i
69
- family = :nix
70
- when /linux/i
71
- family = :nix
72
- when /aix/i
73
- family = :nix
74
- when /cygwin/i
75
- family = :cygwin
76
- else
77
- $stderr.puts "Unknown OS familiy for '#{test_os}'. Please report this bug to #{Launchy::SPEC.email}"
78
- family = :unknown
79
- end
80
- end
81
- end
4
+ class Application
5
+ class << self
6
+ def known_os_families
7
+ @known_os_families ||= [ :windows, :darwin, :nix, :cygwin ]
8
+ end
82
9
 
10
+ def inherited(sub_class)
11
+ application_classes << sub_class
12
+ end
13
+ def application_classes
14
+ @application_classes ||= []
15
+ end
83
16
 
84
- # Determine the appropriate desktop environment for *nix machine. Currently this is
85
- # linux centric. The detection is based upon the detection used by xdg-open from
86
- # http://portland.freedesktop.org/wiki/XdgUtils
87
- def nix_desktop_environment
88
- if not @nix_desktop_environment then
89
- @nix_desktop_environment = :generic
90
- if ENV["KDE_FULL_SESSION"] || ENV["KDE_SESSION_UID"] then
91
- @nix_desktop_environment = :kde
92
- elsif ENV["GNOME_DESKTOP_SESSION_ID"] then
93
- @nix_desktop_environment = :gnome
94
- elsif find_executable("xprop") then
95
- if %x[ xprop -root _DT_SAVE_MODE | grep ' = \"xfce\"$' ].strip.size > 0 then
96
- @nix_desktop_environment = :xfce
97
- end
98
- end
99
- Launchy.log "#{self.class.name} : nix_desktop_environment => '#{@nix_desktop_environment}'"
100
- end
101
- return @nix_desktop_environment
102
- end
103
-
104
- # find an executable in the available paths
105
- def find_executable(bin,*paths)
106
- Application.find_executable(bin,*paths)
17
+ def find_application_class_for(*args)
18
+ Launchy.log "#{self.name} : finding application classes for [#{args.join(' ')}]"
19
+ application_classes.find do |klass|
20
+ Launchy.log "#{self.name} : Trying #{klass.name}"
21
+ if klass.handle?(*args) then
22
+ true
23
+ else
24
+ false
25
+ end
107
26
  end
108
-
109
- # return the current 'host_os' string from ruby's configuration
110
- def my_os
111
- Application.my_os
27
+ end
28
+
29
+ # find an executable in the available paths
30
+ # mkrf did such a good job on this I had to borrow it.
31
+ def find_executable(bin,*paths)
32
+ paths = ENV['PATH'].split(File::PATH_SEPARATOR) if paths.empty?
33
+ paths.each do |path|
34
+ file = File.join(path,bin)
35
+ if File.executable?(file) then
36
+ Launchy.log "#{self.name} : found executable #{file}"
37
+ return file
38
+ end
112
39
  end
113
-
114
- # detect what the current os is and return :windows, :darwin, :nix, or :cygwin
115
- def my_os_family(test_os = my_os)
116
- Application.my_os_family(test_os)
40
+ Launchy.log "#{self.name} : Unable to find `#{bin}' in #{paths.join(', ')}"
41
+ return nil
42
+ end
43
+
44
+ # return the current 'host_os' string from ruby's configuration
45
+ def my_os
46
+ if ENV['LAUNCHY_HOST_OS'] then
47
+ Launchy.log "#{self.name} : Using LAUNCHY_HOST_OS override of '#{ENV['LAUNCHY_HOST_OS']}'"
48
+ return ENV['LAUNCHY_HOST_OS']
49
+ else
50
+ ::Config::CONFIG['host_os']
117
51
  end
118
-
119
- # returns the list of command line application names for the current os. The list
120
- # returned should only contain appliations or commands that actually exist on the
121
- # system. The list members should have their full path to the executable.
122
- def app_list
123
- @app_list ||= self.send("#{my_os_family}_app_list")
52
+ end
53
+
54
+ # detect what the current os is and return :windows, :darwin or :nix
55
+ def my_os_family(test_os = my_os)
56
+ case test_os
57
+ when /mingw/i
58
+ family = :windows
59
+ when /mswin/i
60
+ family = :windows
61
+ when /windows/i
62
+ family = :windows
63
+ when /darwin/i
64
+ family = :darwin
65
+ when /mac os/i
66
+ family = :darwin
67
+ when /solaris/i
68
+ family = :nix
69
+ when /bsd/i
70
+ family = :nix
71
+ when /linux/i
72
+ family = :nix
73
+ when /aix/i
74
+ family = :nix
75
+ when /cygwin/i
76
+ family = :cygwin
77
+ else
78
+ $stderr.puts "Unknown OS familiy for '#{test_os}'. Please report this bug to <jeremy at hinegardner dot org>"
79
+ family = :unknown
124
80
  end
125
-
126
- # On darwin a good general default is the 'open' executable.
127
- def darwin_app_list
128
- Launchy.log "#{self.class.name} : Using 'open' application on darwin."
129
- [ find_executable('open') ]
81
+ end
82
+ end
83
+
84
+
85
+ # Determine the appropriate desktop environment for *nix machine. Currently this is
86
+ # linux centric. The detection is based upon the detection used by xdg-open from
87
+ # http://portland.freedesktop.org/wiki/XdgUtils
88
+ def nix_desktop_environment
89
+ if not defined? @nix_desktop_environment then
90
+ @nix_desktop_environment = :generic
91
+ if ENV["KDE_FULL_SESSION"] || ENV["KDE_SESSION_UID"] then
92
+ @nix_desktop_environment = :kde
93
+ elsif ENV["GNOME_DESKTOP_SESSION_ID"] then
94
+ @nix_desktop_environment = :gnome
95
+ elsif find_executable("xprop") then
96
+ if %x[ xprop -root _DT_SAVE_MODE | grep ' = \"xfce\"$' ].strip.size > 0 then
97
+ @nix_desktop_environment = :xfce
98
+ end
130
99
  end
131
-
132
- # On windows a good general default is the 'start' Command Shell command
133
- def windows_app_list
134
- Launchy.log "#{self.class.name} : Using 'start' command on windows."
100
+ Launchy.log "#{self.class.name} : nix_desktop_environment => '#{@nix_desktop_environment}'"
101
+ end
102
+ return @nix_desktop_environment
103
+ end
104
+
105
+ # find an executable in the available paths
106
+ def find_executable(bin,*paths)
107
+ Application.find_executable(bin,*paths)
108
+ end
109
+
110
+ # return the current 'host_os' string from ruby's configuration
111
+ def my_os
112
+ Application.my_os
113
+ end
114
+
115
+ # detect what the current os is and return :windows, :darwin, :nix, or :cygwin
116
+ def my_os_family(test_os = my_os)
117
+ Application.my_os_family(test_os)
118
+ end
119
+
120
+ # returns the list of command line application names for the current os. The list
121
+ # returned should only contain appliations or commands that actually exist on the
122
+ # system. The list members should have their full path to the executable.
123
+ def app_list
124
+ @app_list ||= self.send("#{my_os_family}_app_list")
125
+ end
126
+
127
+ # On darwin a good general default is the 'open' executable.
128
+ def darwin_app_list
129
+ Launchy.log "#{self.class.name} : Using 'open' application on darwin."
130
+ [ find_executable('open') ]
131
+ end
132
+
133
+ # On windows a good general default is the 'start' Command Shell command
134
+ def windows_app_list
135
+ Launchy.log "#{self.class.name} : Using 'start' command on windows."
135
136
  %w[ start ]
137
+ end
138
+
139
+ # Cygwin uses the windows start but through an explicit execution of the cmd shell
140
+ def cygwin_app_list
141
+ Launchy.log "#{self.class.name} : Using 'cmd /C start' on windows."
142
+ [ "cmd /C start" ]
143
+ end
144
+
145
+ # run the command
146
+ def run(cmd,*args)
147
+ Launchy.log "#{self.class.name} : Spawning on #{my_os_family} : #{cmd} #{args.inspect}"
148
+
149
+ if my_os_family == :windows then
150
+ # NOTE: the command is purposely omitted here because
151
+ # running the filename via "cmd /c" is the same as
152
+ # running "start filename" at the command-prompt
153
+ #
154
+ # furthermore, when "cmd /c start filename" is
155
+ # run, the shell interprets it as two commands:
156
+ # (1) "start" opens a new terminal, and (2)
157
+ # "filename" causes the file to be launched.
158
+ system 'cmd', '/c', *args
159
+ else
160
+ # fork, and the child process should NOT run any exit handlers
161
+ child_pid = fork do
162
+ # NOTE: we pass a dummy argument *before*
163
+ # the actual command to prevent sh
164
+ # from silently consuming our actual
165
+ # command and assigning it to $0!
166
+ dummy = ''
167
+ system 'sh', '-c', '"$@" >/dev/null 2>&1', dummy, cmd, *args
168
+ exit!
136
169
  end
137
-
138
- # Cygwin uses the windows start but through an explicit execution of the cmd shell
139
- def cygwin_app_list
140
- Launchy.log "#{self.class.name} : Using 'cmd /C start' on windows."
141
- [ "cmd /C start" ]
142
- end
143
-
144
- # run the command
145
- def run(cmd,*args)
146
- args.unshift(cmd)
147
- cmd_line = args.join(' ')
148
- Launchy.log "#{self.class.name} : Spawning on #{my_os_family} : #{cmd_line}"
149
-
150
- if my_os_family == :windows then
151
- system cmd_line
152
- else
153
- # fork, and the child process should NOT run any exit handlers
154
- child_pid = fork do
155
- cmd_line += " > /dev/null 2>&1"
156
- system cmd_line
157
- exit!
158
- end
159
- Process.detach(child_pid)
160
- end
161
- end
170
+ Process.detach(child_pid)
171
+ end
162
172
  end
173
+ end
163
174
  end