Sri Lanka were bowled out for 211 in their second innings as South Africa closed in on victory on the third day of the second Test at the Wanderers Stadium in Johannesburg on Tuesday.
Needing 67 runs to complete a 2-0 series sweep, South Africa were 24 for no wicket at lunch.
Sri Lankan captain Dimuth Karunaratne completed his tenth Test century early in the day after resuming on 91 but his dismissal for 103 started a slide in which Sri Lanka lost their last six wickets for 35 runs.
Lungi Ngidi took four for 44 and fellow fast bowler Lutho Sipamla ripped through the tail to take three for 40.
Karunaratne and Niroshan Dickwella started brightly after Sri Lanka resumed on 150 for four. Karunatne went to a 123-ball century with two successive boundaries off Anrich Nortje but an attempted pull off the same bowler looped off a top edge to backward square leg.
Dickwella was caught at mid-off off Ngidi in the next over.
Aiden Markram and Dean Elgar batted aggressively at the start of the final innings but Markram needed a review by the television umpire after edging Vishwa Fernando low to Kusal Mendis at second slip in the last over before lunch when he had 14. Replays showed that Mendis, diving forward, had caught the ball on the bounce.
At Lunch: South Africa 302 and 24 for 0 (Markram 16*, Elgar 8*) need a further 43 to beat Sri Lanka 157 and 211 (Karunaratne 103, Ngidi 4-44)