Re: [Spice-devel] [vdagent] Make sure the child is able to connect to the X server before exiting the mainline.
On 06/24/2014 12:05 AM, Jeremy White wrote: This allows the vdagent to be used in the Xsetup phase of an xdm session; otherwise, its X11 connection fails because of the greeter display grab. relies on the fact the socketpair fd's are never 0 (i.e. fd[1] below is never 0). Which I think is wrong, but only if you close the default fd 0, which you won't, so fine by me. ACK. Signed-off-by: Jeremy White jwh...@codeweavers.com --- src/vdagent.c | 50 -- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/src/vdagent.c b/src/vdagent.c index d7f7aba..905ff5b 100644 --- a/src/vdagent.c +++ b/src/vdagent.c @@ -35,6 +35,7 @@ #include sys/stat.h #include spice/vd_agent.h #include glib.h +#include poll.h #include udscs.h #include vdagentd-proto.h @@ -151,9 +152,34 @@ static void quit_handler(int sig) quit = 1; } -void daemonize(void) +/* When we daemonize, it is useful to have the main process + wait to make sure the X connection worked. We wait up + to 10 seconds to get an 'all clear' from the child + before we exit. If we don't, we're able to exit with a + status that indicates an error occured */ +void wait_and_exit(int s) { -int x, retval = 0; +char buf[4]; +struct pollfd p; +p.fd = s; +p.events = POLLIN; + +if (poll(p, 1, 1) 0) +if (read(s, buf, sizeof(buf)) 0) +exit(0); + +exit(1); +} + +int daemonize(void) +{ +int x; +int fd[2]; + +if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd)) { +syslog(LOG_ERR, socketpair : %s, strerror(errno)); +exit(1); +} /* detach from terminal */ switch (fork()) { @@ -161,13 +187,17 @@ void daemonize(void) close(0); close(1); close(2); setsid(); x = open(/dev/null, O_RDWR); x = dup(x); x = dup(x); -break; +close(fd[0]); +return fd[1]; case -1: syslog(LOG_ERR, fork: %s, strerror(errno)); -retval = 1; +exit(1); default: -exit(retval); +close(fd[1]); +wait_and_exit(fd[0]); } + +return 0; } static int file_test(const char *path) @@ -182,6 +212,7 @@ int main(int argc, char *argv[]) fd_set readfds, writefds; int c, n, nfds, x11_fd; int do_daemonize = 1; +int parent_socket = 0; int x11_sync = 0; struct sigaction act; @@ -236,7 +267,7 @@ int main(int argc, char *argv[]) } if (do_daemonize) -daemonize(); +parent_socket = daemonize(); reconnect: if (version_mismatch) { @@ -275,6 +306,13 @@ reconnect: vdagent_file_xfers = vdagent_file_xfers_create(client, fx_dir, fx_open_dir, debug); +if (parent_socket) { +if (write(parent_socket, OK, 2) != 2) +syslog(LOG_WARNING, Parent already gone.); +close(parent_socket); +parent_socket = 0; +} + while (client !quit) { FD_ZERO(readfds); FD_ZERO(writefds); ___ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel
Re: [Spice-devel] [vdagent] Make sure the child is able to connect to the X server before exiting the mainline.
On 06/24/2014 12:05 AM, Jeremy White wrote: This allows the vdagent to be used in the Xsetup phase of an xdm session; otherwise, its X11 connection fails because of the greeter display grab. But could you make the comment contain the discussion where you explained this in more detail? Signed-off-by: Jeremy White jwh...@codeweavers.com --- src/vdagent.c | 50 -- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/src/vdagent.c b/src/vdagent.c index d7f7aba..905ff5b 100644 --- a/src/vdagent.c +++ b/src/vdagent.c @@ -35,6 +35,7 @@ #include sys/stat.h #include spice/vd_agent.h #include glib.h +#include poll.h #include udscs.h #include vdagentd-proto.h @@ -151,9 +152,34 @@ static void quit_handler(int sig) quit = 1; } -void daemonize(void) +/* When we daemonize, it is useful to have the main process + wait to make sure the X connection worked. We wait up + to 10 seconds to get an 'all clear' from the child + before we exit. If we don't, we're able to exit with a + status that indicates an error occured */ +void wait_and_exit(int s) { -int x, retval = 0; +char buf[4]; +struct pollfd p; +p.fd = s; +p.events = POLLIN; + +if (poll(p, 1, 1) 0) +if (read(s, buf, sizeof(buf)) 0) +exit(0); + +exit(1); +} + +int daemonize(void) +{ +int x; +int fd[2]; + +if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd)) { +syslog(LOG_ERR, socketpair : %s, strerror(errno)); +exit(1); +} /* detach from terminal */ switch (fork()) { @@ -161,13 +187,17 @@ void daemonize(void) close(0); close(1); close(2); setsid(); x = open(/dev/null, O_RDWR); x = dup(x); x = dup(x); -break; +close(fd[0]); +return fd[1]; case -1: syslog(LOG_ERR, fork: %s, strerror(errno)); -retval = 1; +exit(1); default: -exit(retval); +close(fd[1]); +wait_and_exit(fd[0]); } + +return 0; } static int file_test(const char *path) @@ -182,6 +212,7 @@ int main(int argc, char *argv[]) fd_set readfds, writefds; int c, n, nfds, x11_fd; int do_daemonize = 1; +int parent_socket = 0; int x11_sync = 0; struct sigaction act; @@ -236,7 +267,7 @@ int main(int argc, char *argv[]) } if (do_daemonize) -daemonize(); +parent_socket = daemonize(); reconnect: if (version_mismatch) { @@ -275,6 +306,13 @@ reconnect: vdagent_file_xfers = vdagent_file_xfers_create(client, fx_dir, fx_open_dir, debug); +if (parent_socket) { +if (write(parent_socket, OK, 2) != 2) +syslog(LOG_WARNING, Parent already gone.); +close(parent_socket); +parent_socket = 0; +} + while (client !quit) { FD_ZERO(readfds); FD_ZERO(writefds); ___ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel