Bug 571 - Fix attached for Job Control bug in ASH shell.
Summary: Fix attached for Job Control bug in ASH shell.
Status: RESOLVED FIXED
Alias: None
Product: Busybox
Classification: Unclassified
Component: Other (show other bugs)
Version: unspecified
Hardware: PC Windows
: P3 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-08-15 19:08 UTC by Oliver Mattos
Modified: 2009-08-22 17:17 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build: busybox 1.13.4-latest


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Oliver Mattos 2009-08-15 19:08:17 UTC
Job control in ASH is broken.

Test script:
# sleep 20 &
# jobs %sle

Expected output:
# sleep 20 &
# jobs %sle
[1] + Running      sleep 20
# _

Actual Output:
# sleep 20 &
# jobs %sle
-sh: jobs: %sle: ambiguous
# _

Cause:
in busybox/shell/ash.c:getjob:

        found = 0;
        while (1) {
                if (!jp)
                        goto err;
                if (match(jp->ps[0].cmd, p)) {
                        if (found)
                                goto err;
                        found = jp;
                        err_msg = "%s: ambiguous";
                }
                jp = jp->prev_job;
        }

Fix:
The above code can NEVER work, because there is no exit from the while loop even if the correct job is found.  It should be replaced with this:

        found = 0;
        while (jp) {
                if (match(jp->ps[0].cmd, p)) {
                        if (found)
                                goto err;
                        found = jp;
                        err_msg = "%s: ambiguous";
                }
                jp = jp->prev_job;
        }
        if (!found)
                goto err;

Note that it appears err_msg isn't set before going to err, but it is set at the start of the function.

I'm not a regular around here, so I'll leave this here for someone with commit access to make this change.
Comment 1 Oliver Mattos 2009-08-15 22:43:32 UTC
Sorry - just read through this again and realised I was one line short.  The working code is:

         found = 0;
         while (jp) {
                 if (match(jp->ps[0].cmd, p)) {
                         if (found)
                                 goto err;
                         found = jp;
                         err_msg = "%s: ambiguous";
                 }
                 jp = jp->prev_job;
         }
         if (!found)
                 goto err;
         jp=found;


Comment 2 Denys Vlasenko 2009-08-17 00:12:38 UTC
Applied to git. Thanks!