Dilruwan Perera helped Sri Lanka maintain control of the second Test in Colombo on the third day - despite the efforts of South Africa captain Hashim Amla.
The hosts dismissed the Proteas for 282 and reached 11 without loss in their second innings for an overall advantage of 150.
Perera was the pick of the Sri Lanka bowlers, taking 5-69, while fellow off-spinner Rangana Herath provided excellent support with 4-71.
However, Amla was the day's outstanding performer, showing his team-mates the way with the bat as he turned his overnight 46 not out into an unbeaten 139.
South Africa resumed the third morning on 98 for three and Amla and AB de Villiers added 52 before Perera started his onslaught, trapping de Villiers lbw for 37 and two balls later bowling Quinton de Kock.
JP Duminy had made a painstaking three when he was stumped by debutant wicketkeeper Niroshan Dickwella off Herath - the 58th ball Duminy had faced - and it was 204 for seven when Perera bowled Vernon Philander for nine.
Dale Steyn had contributed 30 to an eighth-wicket stand of 47 with Amla when he was caught by Kumar Sangakkara at long-off off Herath.
And 251 for eight became 279 for nine when Imran Tahir became Herath's fourth victim of the innings when he was caught by Upul Tharanga at deep mid-off for 15.
The tourists' effort was over just two runs later, Morne Morkel falling first ball, caught at forward short-leg by Kaushal Silva to give Perera his five-wicket haul.
It all means the hosts are in a good position to level the two-match series, having lost the opener in Galle by 153 runs.