On 2013-04-12 09:52, "BRAGA, Bruno" <[email protected]> wrote:
> Michael,
>
> I noticed that the commands executed with && do not always work...
> triggering the lock and unlocking it right away always work, but every time
> I leave the machine locked for longer time (hour or more), the posthook
> script is never called.
> Sorry it is hard to reproduce/troubleshoot.
>
> For example:
>
> bindsym Control+mod1+l exec ~/.i3/i3lock-prehook.sh && i3lock -c 000000 &&
> ~/.i3/i3lock-posthook.sh
>
> the i3lock-prehook.sh script is:
>
> #!/bin/bash
> logger -t "prehook" 'Executed.'
>
> the i3lock-posthook.sh script is:
>
> #!/bin/bash
> logger -t "posthook" 'Executed.'
>
> ----------------
>
> Dont know if this is even worth pursuing.... I solved the problem by
> wrapping it all into a single script:
>
> bindsym Control+mod1+l exec ~/.i3/i3lock.sh
>
> the i3lock.sh script is:
>
> #!/bin/bash
> logger -t "prehook" 'Executed.'
> i3lock -c 000000
> logger -t "posthook" 'Executed.'
>
> (which will obivously work even if something goes wrong with i3lock).
Hi Bruno,
I think this may be a bug in i3lock. The main i3 code calls the command
you have configured in your startup file with the execl() equivalent of:
# From startup_application() in src/startup.c:134
$SHELL -c "~/.i3/i3lock-prehook.sh && i3lock -c 000000 &&
~/.i3/i3lock-posthook.sh"
So if 'i3lock -c 000000' is running, but the next part of the command
never runs, it means that the shell got an exit code != 0 from i3lock.
Since i3lock is not failing to start, but it has been running for a
while, the only reason I can think of that would cause a non-zero exit
code is that main() in i3lock.s never calls 'return 0' when it's done.
The last parts of i3lock's main() function are:
int main(int argc, char *argv[]) {
...
/* Invoke the event callback once to catch all the events which were
* received up until now. ev will only pick up new events (when the
X11
* file descriptor becomes readable). */
ev_invoke(main_loop, xcb_check, 0);
ev_loop(main_loop, 0);
}
After ev_loop() is done, there is no return statement, so if ev_loop
happens to return, main() is free to return a random value, e.g. the
contents of a register or some random value from the stack.
This may explain why "it sometimes works".
Can you try adding this return statement to i3lock's main() function,
and then rebuild i3lock from source?
int main(int argc, char *argv[]) {
...
/* Invoke the event callback once to catch all the events which were
* received up until now. ev will only pick up new events (when the
X11
* file descriptor becomes readable). */
ev_invoke(main_loop, xcb_check, 0);
ev_loop(main_loop, 0);
+ return EXIT_SUCCESS;
}