mirror of
https://github.com/samsonjs/csc360-a1-shell.git
synced 2026-04-27 14:57:43 +00:00
[ruby] Implement bglist and bgkill
This commit is contained in:
parent
e7b73fa309
commit
5bb03eb2a2
2 changed files with 62 additions and 18 deletions
|
|
@ -28,6 +28,28 @@ module Shell
|
||||||
job_control.exec_command(cmd, args, background: true)
|
job_control.exec_command(cmd, args, background: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def builtin_bglist(_args)
|
||||||
|
jobs = job_control.list
|
||||||
|
puts unless jobs.empty?
|
||||||
|
jobs.each do |job|
|
||||||
|
puts job_control.format_job(job)
|
||||||
|
end
|
||||||
|
plural = jobs.count == 1 ? '' : 's'
|
||||||
|
puts "#{jobs.count} background job#{plural}"
|
||||||
|
0
|
||||||
|
end
|
||||||
|
|
||||||
|
def builtin_bgkill(args)
|
||||||
|
if args.count != 1
|
||||||
|
logger.warn 'Usage: bgkill <job>'
|
||||||
|
return -1
|
||||||
|
end
|
||||||
|
|
||||||
|
job_id = args.shift.to_i
|
||||||
|
job_control.kill(job_id)
|
||||||
|
0
|
||||||
|
end
|
||||||
|
|
||||||
def builtin_cd(args)
|
def builtin_cd(args)
|
||||||
Dir.chdir args.first
|
Dir.chdir args.first
|
||||||
0
|
0
|
||||||
|
|
|
||||||
|
|
@ -15,24 +15,6 @@ module Shell
|
||||||
@logger = logger || Logger.instance
|
@logger = logger || Logger.instance
|
||||||
end
|
end
|
||||||
|
|
||||||
def trap_sigchld
|
|
||||||
# handler for SIGCHLD when a child's state changes
|
|
||||||
Signal.trap('CHLD') do |_signo|
|
|
||||||
pid = Process.waitpid(-1, Process::WNOHANG)
|
|
||||||
if pid.nil?
|
|
||||||
# no-op
|
|
||||||
elsif (job = @jobs_by_pid[pid])
|
|
||||||
time = Time.now.strftime('%T')
|
|
||||||
job_text = yellow('job ', job.id, ' exited')
|
|
||||||
args = job.args.inspect
|
|
||||||
puts "\n[#{time}] #{job_text} #{white('(pid ', pid, ')')}: #{green(job.cmd)} #{args}"
|
|
||||||
else
|
|
||||||
warn "\n#{yellow('[WARN]')} No job found for child with PID #{pid}"
|
|
||||||
end
|
|
||||||
Readline.refresh_line
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def exec_command(cmd, args, background: false)
|
def exec_command(cmd, args, background: false)
|
||||||
unless (path = resolve_executable(cmd))
|
unless (path = resolve_executable(cmd))
|
||||||
warn "#{red('[ERROR]')} command not found: #{cmd}"
|
warn "#{red('[ERROR]')} command not found: #{cmd}"
|
||||||
|
|
@ -61,6 +43,46 @@ module Shell
|
||||||
-5
|
-5
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def kill(job_id)
|
||||||
|
job = @jobs_by_pid.values.detect { |j| j.id == job_id }
|
||||||
|
if job.nil?
|
||||||
|
logger.warn "No job found with ID #{job_id}"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
Process.kill('TERM', job.pid)
|
||||||
|
rescue Errno::ESRCH
|
||||||
|
logger.warn "No such proccess: #{job.pid}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def list
|
||||||
|
@jobs_by_pid.values.sort_by(&:id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def format_job(job)
|
||||||
|
args = job.args.join(' ')
|
||||||
|
"#{yellow(job.id)}: #{white('(pid ', job.pid, ')')} #{green(job.cmd)} #{args}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def trap_sigchld
|
||||||
|
# handler for SIGCHLD when a child's state changes
|
||||||
|
Signal.trap('CHLD') do |_signo|
|
||||||
|
pid = Process.waitpid(-1, Process::WNOHANG)
|
||||||
|
if pid.nil?
|
||||||
|
# no-op
|
||||||
|
elsif (job = @jobs_by_pid[pid])
|
||||||
|
@jobs_by_pid.delete(pid)
|
||||||
|
time = Time.now.strftime('%T')
|
||||||
|
job_text = yellow('job ', job.id, ' exited')
|
||||||
|
args = job.args.join(' ')
|
||||||
|
puts "\n[#{time}] #{job_text} #{white('(pid ', job.pid, ')')}: #{green(job.cmd)} #{args}"
|
||||||
|
else
|
||||||
|
warn "\n#{yellow('[WARN]')} No job found for child with PID #{pid}"
|
||||||
|
end
|
||||||
|
Readline.refresh_line
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Return absolute and relative paths directly, or searches PATH for a
|
# Return absolute and relative paths directly, or searches PATH for a
|
||||||
# matching executable with the given filename and returns its path.
|
# matching executable with the given filename and returns its path.
|
||||||
# Returns nil when no such command was found.
|
# Returns nil when no such command was found.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue