[PATCH] with cmd:parallel>1 and cmd:fail-exit true only the first command will be executed
Fernando Gutierrez <[email protected]> Wed, 1 Jun 2011 18:57:47 +0200
| Newsgroups | gmane.network.lftp.devel |
|---|---|
| Message-ID | <[email protected]> |
--bcaec52160bfb8687204a4a96c24 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable **Problem: With cmd:parallel=3D1 it works fine because CmdExec::Do() waits (returns early) until the running job is finished before spawning the next one in exec_parsed_command(). When it finishes, the exit code of that job is stored in exit_code, that exec_parsed_command() will check (when cmd:fail-exit=3Dtrue) in order to see if it must end the program (removing the feeder and emptying the buffer). However when you have several in parallel, if CMD(something) doesn't set exit_code=3D0, the next time exec_parsed_command() is called (that is, the next command in the buffer) will think there was an error and will prevent the rest of the commands from executing. exit_code is set to 1 in exec_parsed_command() before making the new job (new_job=3Dc->creator(this);) =C2=A0creator(this) calls a CMD(something= ) in commands.cc and that will sometimes set exit_code=3D0 when it finishes successfully, or ignore it (exit_code being 1) **Tests: .lftp/rc: set cmd:fail-exit true; set cmd:parallel 2; lftp -f file: -First example file: open fish://user:pass@ip; chmod 755 a; chmod 755 a; chmod will only be executed once -Second example file: get -c http://file1; get -c http://file2; Only file1 will be downloaded. **Fix: exit_code must be 0, or the fail-exit check must be changed to only run if a job just finished, which isn't easy because some commands don't make new jobs, the finish and just leave exit_code=3D1. After making a new job, if a new object has actually been created, AddNewJob is called. If the command is in the background, it is executed and if not finished, suspended (put in the background) with SuspendJob. The interesting part is that function also sets exit_code=3D0. When a job finishes, its status code is stored in exit_code. I've tried to find if that wasn't always the case, but it seems all external and built-in commands do it. So exit_code=3D1 shouldn't be necessary while the jobs are running. I thought maybe it was made that way because a job could somehow finish in an error state and bypassing the place where its status code is put into exit_code, but I didn't find any of such cases. Also, because you can background a job whenever you want, that means the exit_code of its CmdExec can be changed to 0 at any moment, telling me it's value is not important. If a job is not created in exec_parsed_command(), then the exit_code is relevant, because that means the command has already been executed and exit_code is storing a real value. However, if there is a new job, it is supposed to exit and give a code. So, would the proper fix be adding exit_code=3D0 to AddNewJob? it works, and that's what I implemented. --bcaec52160bfb8687204a4a96c24 Content-Type: application/octet-stream; name="fail-exit.patch" Content-Disposition: attachment; filename="fail-exit.patch" Content-Transfer-Encoding: base64 X-Attachment-Id: f_go4kq8z80 LS0tIG9yaWcvQ21kRXhlYy5jYwkyMDExLTA0LTI5IDA2OjU4OjI3LjAwMDAwMDAwMCArMDIwMAor KysgcGF0Y2hlZF9sZnRwLTQuMi4zL3NyYy9DbWRFeGVjLmNjCTIwMTEtMDUtMjQgMDk6NTI6MzQu MDAwMDAwMDAwICswMjAwCkBAIC0yNTEsNiArMjUxLDcgQEAKICAgIGlmKG5ld19qb2ItPmpvYm5v PDApCiAgICAgICBuZXdfam9iLT5BbGxvY0pvYm5vKCk7CiAgICBuZXdfam9iLT5TZXRQYXJlbnRG Zyh0aGlzLCFiYWNrZ3JvdW5kKTsKKyAgIGV4aXRfY29kZT0wOwogICAgQWRkV2FpdGluZyhuZXdf am9iKTsKICAgIGlmKGJhY2tncm91bmQpIHsKICAgICAgIFJvbGwobmV3X2pvYik7Cg== --bcaec52160bfb8687204a4a96c24--