]> Pileus Git - ~andy/gtk/blob - gdk/linux-fb/gdkfbswitch.c
Fixes #136082 and #135265, patch by Morten Welinder.
[~andy/gtk] / gdk / linux-fb / gdkfbswitch.c
1 #include <config.h>
2 #include <glib.h>
3
4 #include <stdlib.h>
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #include <sys/un.h>
8 #include <unistd.h>
9
10 #include "gdkfbmanager.h"
11
12 int
13 main (int argc, char *argv[])
14 {
15   int fd;
16   struct sockaddr_un addr;
17   struct msghdr msg = {0};
18   struct cmsghdr *cmsg;
19   struct ucred credentials;
20   struct FBManagerMessage init_msg;
21   struct iovec iov;
22   char buf[CMSG_SPACE (sizeof (credentials))];  /* ancillary data buffer */
23   int *fdptr;
24   int res;
25
26   if (argc != 2)
27     {
28       g_print ("usage: fbswitch <pid>\n");
29       return 1;
30     }
31
32   fd = socket (PF_UNIX, SOCK_STREAM, 0);
33   
34   if (fd < 0)
35     return 1;
36
37   addr.sun_family = AF_UNIX;
38   strcpy (addr.sun_path, "/tmp/.fb.manager");
39
40   if (connect(fd, (struct sockaddr *)&addr, sizeof (addr)) < 0) 
41     {
42       g_print ("connect failed\n");
43       close (fd);
44       return 1;
45     }
46   
47   credentials.pid = getpid ();
48   credentials.uid = geteuid ();
49   credentials.gid = getegid ();
50
51   init_msg.msg_type = FB_MANAGER_NEW_CLIENT;
52   iov.iov_base = &init_msg;
53   iov.iov_len = sizeof (init_msg);
54
55   msg.msg_name = NULL;
56   msg.msg_namelen = 0;
57   msg.msg_iov = &iov;
58   msg.msg_iovlen = 1;
59   msg.msg_control = buf;
60   msg.msg_controllen = sizeof buf;
61   cmsg = CMSG_FIRSTHDR(&msg);
62   cmsg->cmsg_level = SOL_SOCKET;
63   cmsg->cmsg_type = SCM_CREDENTIALS;
64   cmsg->cmsg_len = CMSG_LEN (sizeof (credentials));
65   /* Initialize the payload: */
66   fdptr = (int *)CMSG_DATA (cmsg);
67   memcpy (fdptr, &credentials, sizeof (credentials));
68   /* Sum of the length of all control messages in the buffer: */
69   msg.msg_controllen = cmsg->cmsg_len;
70
71   res = sendmsg (fd, &msg, 0);
72
73   init_msg.msg_type = FB_MANAGER_REQUEST_SWITCH_TO_PID;
74   init_msg.data = atoi (argv[1]);
75   /* Request a switch-to */
76   send (fd, &init_msg, sizeof (init_msg), 0);
77   g_print ("requested a switch to pid %d\n", init_msg.data);
78
79   return 0;
80 }