vdagentd: Fix exit value on fork failure
[vd_agent/hramrach.git] / vdagent.c
blobde60627d666aaa317a9f5f12b5da5b90ee54bee4
1 /* vdagent.c xorg-client to vdagentd (daemon).
3 Copyright 2010 Red Hat, Inc.
5 Red Hat Authors:
6 Hans de Goede <hdegoede@redhat.com>
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <signal.h>
29 #include <sys/select.h>
30 #include <sys/stat.h>
31 #include <spice/vd_agent.h>
33 #include "udscs.h"
34 #include "vdagentd-proto.h"
35 #include "vdagentd-proto-strings.h"
36 #include "vdagent-x11.h"
38 static int verbose = 0;
39 static struct vdagent_x11 *x11 = NULL;
40 static FILE *logfile = NULL;
41 static int quit = 0;
43 void daemon_read_complete(struct udscs_connection **connp,
44 struct udscs_message_header *header, const uint8_t *data)
46 switch (header->type) {
47 case VDAGENTD_MONITORS_CONFIG:
48 vdagent_x11_set_monitor_config(x11, (VDAgentMonitorsConfig *)data);
49 break;
50 case VDAGENTD_CLIPBOARD_REQUEST:
51 vdagent_x11_clipboard_request(x11, header->opaque);
52 break;
53 case VDAGENTD_CLIPBOARD_GRAB:
54 vdagent_x11_clipboard_grab(x11, (uint32_t *)data,
55 header->size / sizeof(uint32_t));
56 break;
57 case VDAGENTD_CLIPBOARD_DATA:
58 vdagent_x11_clipboard_data(x11, header->opaque, data, header->size);
59 break;
60 case VDAGENTD_CLIPBOARD_RELEASE:
61 vdagent_x11_clipboard_release(x11);
62 break;
63 default:
64 if (verbose)
65 fprintf(logfile, "Unknown message from vdagentd type: %d\n",
66 header->type);
70 static void usage(FILE *fp)
72 fprintf(fp,
73 "vdagent -- spice agent xorg client\n"
74 "options:\n"
75 " -h print this text\n"
76 " -d log debug messages\n");
79 static void quit_handler(int sig)
81 quit = 1;
84 int main(int argc, char *argv[])
86 struct udscs_connection *client = NULL;
87 fd_set readfds, writefds;
88 int c, n, nfds, x11_fd, retval = 0;
89 char *home, filename[1024];
90 struct sigaction act;
92 for (;;) {
93 if (-1 == (c = getopt(argc, argv, "-dh")))
94 break;
95 switch (c) {
96 case 'd':
97 verbose++;
98 break;
99 case 'h':
100 usage(stdout);
101 return 0;
102 default:
103 usage(stderr);
104 return 1;
108 memset(&act, 0, sizeof(act));
109 act.sa_flags = SA_RESTART;
110 act.sa_handler = quit_handler;
111 sigaction(SIGINT, &act, NULL);
112 sigaction(SIGHUP, &act, NULL);
113 sigaction(SIGTERM, &act, NULL);
114 sigaction(SIGQUIT, &act, NULL);
116 home = getenv("HOME");
117 if (home) {
118 snprintf(filename, sizeof(filename), "%s/.spice-vdagent", home);
119 n = mkdir(filename, 0755);
120 snprintf(filename, sizeof(filename), "%s/.spice-vdagent/log", home);
121 logfile = fopen(filename, "w");
122 if (!logfile) {
123 fprintf(stderr, "Error opening %s: %s\n", filename,
124 strerror(errno));
125 logfile = stderr;
127 } else {
128 fprintf(stderr, "Could not get home directory, logging to stderr\n");
129 logfile = stderr;
132 client = udscs_connect(VDAGENTD_SOCKET, daemon_read_complete, NULL,
133 vdagentd_messages, VDAGENTD_NO_MESSAGES,
134 verbose? logfile:NULL, logfile);
135 if (!client)
136 return 1;
138 x11 = vdagent_x11_create(client, logfile, verbose);
139 if (!x11) {
140 udscs_destroy_connection(&client);
141 return 1;
144 while (client && !quit) {
145 FD_ZERO(&readfds);
146 FD_ZERO(&writefds);
148 nfds = udscs_client_fill_fds(client, &readfds, &writefds);
149 x11_fd = vdagent_x11_get_fd(x11);
150 FD_SET(x11_fd, &readfds);
151 if (x11_fd >= nfds)
152 nfds = x11_fd + 1;
154 n = select(nfds, &readfds, &writefds, NULL, NULL);
155 if (n == -1) {
156 if (errno == EINTR)
157 continue;
158 fprintf(logfile, "Fatal error select: %s\n", strerror(errno));
159 retval = 1;
160 break;
163 if (FD_ISSET(x11_fd, &readfds))
164 vdagent_x11_do_read(x11);
165 udscs_client_handle_fds(&client, &readfds, &writefds);
166 fflush(logfile);
169 vdagent_x11_destroy(x11);
170 udscs_destroy_connection(&client);
171 fclose(logfile);
173 return retval;