Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
M. Stoeckl
Waypipe
Commits
b8444b37
Commit
b8444b37
authored
May 13, 2019
by
Manuel Stoeckl
Browse files
Relay messages between client and server, but without fds
parent
4b0e9dcf
Changes
6
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
b8444b37
...
...
@@ -5,8 +5,8 @@ way_cflags := $(shell pkg-config --cflags wayland-client wayland-server)
all
:
waypipe
waypipe
:
waypipe.c server.c client.c Makefile
gcc
-ggdb3
$(way_libs)
$(way_cflags)
-o
waypipe waypipe.c server.c client.c
waypipe
:
waypipe.c server.c client.c
util.c util.h
Makefile
gcc
-std
=
c11
-ggdb3
$(way_libs)
$(way_cflags)
-o
waypipe waypipe.c server.c client.c
util.h util.c
clean
:
rm
-f
waypipe
...
...
client.c
View file @
b8444b37
...
...
@@ -23,12 +23,18 @@
* SOFTWARE.
*/
#define _XOPEN_SOURCE 700
#include "util.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <time.h>
#include <unistd.h>
#include <wayland-client-core.h>
...
...
@@ -39,6 +45,7 @@ int run_client(const char *socket_path)
fprintf
(
stderr
,
"Failed to connect to a wayland server.
\n
"
);
return
EXIT_FAILURE
;
}
int
displayfd
=
wl_display_get_fd
(
display
);
struct
sockaddr_un
saddr
;
int
fd
;
...
...
@@ -70,9 +77,13 @@ int run_client(const char *socket_path)
return
EXIT_FAILURE
;
}
int
maxmsg
=
4096
;
char
*
buffer
=
calloc
(
1
,
maxmsg
+
1
);
fprintf
(
stderr
,
"I'm a client on %s!
\n
"
,
socket_path
);
for
(
int
i
=
0
;
i
<
1
;
i
++
)
{
// Q: multiple parallel client support?
// Q: multiple parallel remote client support? then multiplex
// over all accepted clients?
int
client
=
accept
(
fd
,
NULL
,
NULL
);
if
(
client
==
-
1
)
{
...
...
@@ -83,18 +94,86 @@ int run_client(const char *socket_path)
int
bufsize
=
4096
;
char
*
buf
=
calloc
(
bufsize
+
1
,
1
);
while
(
1
)
{
int
nb
=
read
(
client
,
buf
,
bufsize
);
if
(
nb
<=
0
)
{
fprintf
(
stderr
,
"Read failed, stopping
\n
"
);
// pselect multiple.
fd_set
readfds
;
FD_ZERO
(
&
readfds
);
FD_SET
(
client
,
&
readfds
);
FD_SET
(
displayfd
,
&
readfds
);
struct
timespec
timeout
=
{
.
tv_sec
=
0
,
.
tv_nsec
=
700000000L
};
int
maxfd
=
client
>
displayfd
?
client
:
displayfd
;
int
r
=
pselect
(
maxfd
+
1
,
&
readfds
,
NULL
,
NULL
,
&
timeout
,
NULL
);
if
(
r
==
-
1
)
{
fprintf
(
stderr
,
"Select failed, stopping
\n
"
);
break
;
}
else
{
fprintf
(
stderr
,
"Read with %d bytes of data |%s|
\n
"
,
nb
,
buf
);
}
fprintf
(
stderr
,
"Post select %d %d %d
\n
"
,
r
,
FD_ISSET
(
client
,
&
readfds
),
FD_ISSET
(
displayfd
,
&
readfds
));
if
(
r
==
0
)
{
const
char
*
msg
=
"magic"
;
ssize_t
nb
=
write
(
client
,
msg
,
strlen
(
msg
)
+
1
);
if
(
nb
==
-
1
)
{
fprintf
(
stderr
,
"Write failed, retrying anyway
\n
"
);
}
continue
;
}
if
(
FD_ISSET
(
client
,
&
readfds
))
{
fprintf
(
stderr
,
"client isset
\n
"
);
int
rc
=
iovec_read
(
client
,
buffer
,
maxmsg
,
NULL
,
NULL
);
if
(
rc
==
-
1
)
{
fprintf
(
stderr
,
"FD Read failure %ld: %s
\n
"
,
rc
,
strerror
(
errno
));
break
;
}
fprintf
(
stderr
,
"read bytes: %d
\n
"
,
rc
);
if
(
rc
>
0
)
{
int
wc
=
iovec_write
(
displayfd
,
buffer
,
rc
,
NULL
,
NULL
);
if
(
wc
==
-
1
)
{
fprintf
(
stderr
,
"FD Write failure %ld: %s
\n
"
,
wc
,
strerror
(
errno
));
break
;
}
}
else
{
fprintf
(
stderr
,
"the other side shut down
\n
"
);
break
;
}
}
if
(
FD_ISSET
(
displayfd
,
&
readfds
))
{
fprintf
(
stderr
,
"displayfd isset
\n
"
);
int
rc
=
iovec_read
(
displayfd
,
buffer
,
maxmsg
,
NULL
,
NULL
);
if
(
rc
==
-
1
)
{
fprintf
(
stderr
,
"CS Read failure %ld: %s
\n
"
,
rc
,
strerror
(
errno
));
break
;
}
if
(
rc
>
0
)
{
int
wc
=
iovec_write
(
client
,
buffer
,
rc
,
NULL
,
NULL
);
if
(
wc
==
-
1
)
{
fprintf
(
stderr
,
"CS Write failure %ld: %s
\n
"
,
wc
,
strerror
(
errno
));
break
;
}
}
else
{
fprintf
(
stderr
,
"the display shut down
\n
"
);
break
;
}
}
}
fprintf
(
stderr
,
"...
\n
"
);
}
fprintf
(
stderr
,
"Closing
\n
"
);
close
(
displayfd
);
close
(
fd
);
unlink
(
socket_path
);
...
...
server.c
View file @
b8444b37
...
...
@@ -23,14 +23,22 @@
* SOFTWARE.
*/
#define _POSIX_C_SOURCE 200112L
#define _XOPEN_SOURCE 700
#include "util.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include <wayland-server-core.h>
...
...
@@ -43,20 +51,15 @@ int run_server(const char *socket_path, int app_argc, char *const app_argv[])
}
fprintf
(
stderr
,
"
\n
"
);
struct
wl_display
*
display
=
wl_display_create
();
// create another socketpair; one goes to display; one goes to child
int
csockpair
[
2
];
socketpair
(
AF_UNIX
,
SOCK_STREAM
,
0
,
csockpair
);
if
(
wl_display_add_socket_fd
(
display
,
csockpair
[
0
])
==
-
1
)
{
fprintf
(
stderr
,
"Failed to add socket to display object
\n
"
);
wl_display_destroy
(
display
);
return
EXIT_FAILURE
;
}
int
flags
=
fcntl
(
csockpair
[
0
],
F_GETFD
);
fcntl
(
csockpair
[
0
],
F_SETFD
,
flags
|
FD_CLOEXEC
);
pid_t
pid
=
fork
();
if
(
pid
==
-
1
)
{
fprintf
(
stderr
,
"Fork failed
\n
"
);
wl_display_destroy
(
display
);
return
EXIT_FAILURE
;
}
else
if
(
pid
==
0
)
{
char
bufs2
[
16
];
...
...
@@ -70,6 +73,14 @@ int run_server(const char *socket_path, int app_argc, char *const app_argv[])
fprintf
(
stderr
,
"Failed to execv: %s
\n
"
,
strerror
(
errno
));
return
EXIT_FAILURE
;
}
struct
wl_display
*
display
=
wl_display_create
();
if
(
wl_display_add_socket_fd
(
display
,
csockpair
[
0
])
==
-
1
)
{
fprintf
(
stderr
,
"Failed to add socket to display object
\n
"
);
wl_display_destroy
(
display
);
return
EXIT_FAILURE
;
}
int
status
;
struct
sockaddr_un
saddr
;
...
...
@@ -95,11 +106,90 @@ int run_server(const char *socket_path, int app_argc, char *const app_argv[])
return
EXIT_FAILURE
;
}
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
sleep
(
1
);
char
msg
[
256
];
sprintf
(
msg
,
"Message #%d"
,
i
);
write
(
fd
,
msg
,
strlen
(
msg
)
+
1
);
// A connection has already been established
int
client_socket
=
csockpair
[
0
];
/** Main select loop:
* fd -> csockpair[0]
* csockpair[0] -> fd
* 1 second timer (poll waitpid) */
struct
timespec
timeout
=
{.
tv_sec
=
0
,
.
tv_nsec
=
500000000L
};
fd_set
readfds
;
int
iter
=
0
;
int
maxmsg
=
4096
;
char
*
buffer
=
calloc
(
1
,
maxmsg
+
1
);
while
(
true
)
{
iter
++
;
if
(
iter
>
10
)
{
break
;
}
FD_ZERO
(
&
readfds
);
FD_SET
(
fd
,
&
readfds
);
FD_SET
(
client_socket
,
&
readfds
);
int
maxfd
=
fd
>
client_socket
?
fd
:
client_socket
;
int
r
=
pselect
(
maxfd
+
1
,
&
readfds
,
NULL
,
NULL
,
&
timeout
,
NULL
);
if
(
r
<
0
)
{
fprintf
(
stderr
,
"Error selecting fds: %s
\n
"
,
strerror
(
errno
));
return
EXIT_FAILURE
;
}
if
(
r
==
0
)
{
// timeout!
fprintf
(
stderr
,
"timeout,??
\n
"
);
}
else
{
fprintf
(
stderr
,
"%d are set
\n
"
,
r
);
}
if
(
FD_ISSET
(
fd
,
&
readfds
))
{
fprintf
(
stderr
,
"Readfd isset
\n
"
);
int
rc
=
iovec_read
(
fd
,
buffer
,
maxmsg
,
NULL
,
NULL
);
if
(
rc
==
-
1
)
{
fprintf
(
stderr
,
"FD Read failure %ld: %s
\n
"
,
rc
,
strerror
(
errno
));
break
;
}
fprintf
(
stderr
,
"Read from conn %d bytes
\n
"
,
rc
);
if
(
rc
>
0
)
{
int
wc
=
iovec_write
(
client_socket
,
buffer
,
rc
,
NULL
,
NULL
);
if
(
wc
==
-
1
)
{
fprintf
(
stderr
,
"FD Write failure %ld: %s
\n
"
,
wc
,
strerror
(
errno
));
break
;
}
}
else
{
fprintf
(
stderr
,
"the other side shut down
\n
"
);
break
;
}
}
if
(
FD_ISSET
(
client_socket
,
&
readfds
))
{
fprintf
(
stderr
,
"client socket isset
\n
"
);
int
rc
=
iovec_read
(
client_socket
,
buffer
,
maxmsg
,
NULL
,
NULL
);
if
(
rc
==
-
1
)
{
fprintf
(
stderr
,
"CS Read failure %ld: %s
\n
"
,
rc
,
strerror
(
errno
));
break
;
}
if
(
rc
>
0
)
{
int
wc
=
iovec_write
(
fd
,
buffer
,
rc
,
NULL
,
NULL
);
if
(
wc
==
-
1
)
{
fprintf
(
stderr
,
"CS Write failure %ld: %s
\n
"
,
wc
,
strerror
(
errno
));
break
;
}
}
else
{
fprintf
(
stderr
,
"the client shut down
\n
"
);
break
;
}
}
if
(
waitpid
(
pid
,
&
status
,
WNOHANG
)
>
0
)
{
break
;
}
}
close
(
fd
);
...
...
test.sh
View file @
b8444b37
...
...
@@ -2,8 +2,9 @@
root
=
`
pwd
`
# program=`which bash`
program
=
`
which weston-flower
`
#program=`which bash`
# program=`which weston-flower`
program
=
`
which demo.py
`
(
$root
/waypipe client /tmp/socket-client 2>&1 |
sed
's/.*/\x1b[33m&\x1b[0m/'
)
&
# ssh-to-self; should have a local keypair set up
...
...
util.c
0 → 100644
View file @
b8444b37
/*
* Copyright © 2019 Manuel Stoeckl
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/un.h>
#include <unistd.h>
int
iovec_read
(
int
conn
,
char
*
buf
,
size_t
buflen
,
int
*
fds
,
int
*
numfds
)
{
char
cmsgdata
[
(
CMSG_LEN
(
28
*
sizeof
(
int32_t
)))
];
struct
iovec
the_iovec
;
the_iovec
.
iov_len
=
buflen
;
the_iovec
.
iov_base
=
buf
;
struct
msghdr
msg
;
msg
.
msg_name
=
NULL
;
msg
.
msg_namelen
=
0
;
msg
.
msg_iov
=
&
the_iovec
;
msg
.
msg_iovlen
=
1
;
msg
.
msg_control
=
&
cmsgdata
;
msg
.
msg_controllen
=
sizeof
(
cmsgdata
);
msg
.
msg_flags
=
0
;
ssize_t
ret
=
recvmsg
(
conn
,
&
msg
,
MSG_DONTWAIT
);
// parse FDS
return
ret
;
}
int
iovec_write
(
int
conn
,
char
*
buf
,
size_t
buflen
,
int
*
fds
,
int
*
numfds
)
{
// char cmsgdata[ (CMSG_LEN(28 * sizeof(int32_t))) ];
struct
iovec
the_iovec
;
the_iovec
.
iov_len
=
buflen
;
the_iovec
.
iov_base
=
buf
;
struct
msghdr
msg
;
msg
.
msg_name
=
NULL
;
msg
.
msg_namelen
=
0
;
msg
.
msg_iov
=
&
the_iovec
;
msg
.
msg_iovlen
=
1
;
msg
.
msg_control
=
NULL
;
msg
.
msg_controllen
=
0
;
msg
.
msg_flags
=
0
;
ssize_t
ret
=
sendmsg
(
conn
,
&
msg
,
0
);
// parse FDS
return
ret
;
}
util.h
0 → 100644
View file @
b8444b37
/*
* Copyright © 2019 Manuel Stoeckl
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef WAYPIPE_UTIL_H
#define WAYPIPE_UTIL_H
#include <stdint.h>
#include <stddef.h>
int
iovec_read
(
int
socket
,
char
*
buf
,
size_t
buflen
,
int
*
fds
,
int
*
numfds
);
int
iovec_write
(
int
conn
,
char
*
buf
,
size_t
buflen
,
int
*
fds
,
int
*
numfds
);
#endif // WAYPIPE_UTIL_H
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment