Commit 9a6979ca authored by Manuel Stoeckl's avatar Manuel Stoeckl
Browse files

Renaming variables, and start fd identification

parent b8444b37
#!/bin/sh
clang-format -style=file --assume-filename=C -i waypipe.c server.c client.c
clang-format -style=file --assume-filename=C -i waypipe.c server.c client.c util.h util.c
......@@ -48,7 +48,7 @@ int run_client(const char *socket_path)
int displayfd = wl_display_get_fd(display);
struct sockaddr_un saddr;
int fd;
int channelsock;
if (strlen(socket_path) >= sizeof(saddr.sun_path)) {
fprintf(stderr, "Socket path is too long and would be truncated: %s\n",
......@@ -58,21 +58,21 @@ int run_client(const char *socket_path)
saddr.sun_family = AF_UNIX;
strncpy(saddr.sun_path, socket_path, sizeof(saddr.sun_path) - 1);
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd == -1) {
channelsock = socket(AF_UNIX, SOCK_STREAM, 0);
if (channelsock == -1) {
fprintf(stderr, "Error creating socket: %s\n", strerror(errno));
return EXIT_FAILURE;
}
if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) {
if (bind(channelsock, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) {
fprintf(stderr, "Error binding socket: %s\n", strerror(errno));
close(fd);
close(channelsock);
return EXIT_FAILURE;
}
if (listen(fd, 1) == -1) {
if (listen(channelsock, 1) == -1) {
fprintf(stderr, "Error listening to socket: %s\n",
strerror(errno));
close(fd);
close(channelsock);
unlink(socket_path);
return EXIT_FAILURE;
}
......@@ -85,8 +85,8 @@ int run_client(const char *socket_path)
// Q: multiple parallel remote client support? then multiplex
// over all accepted clients?
int client = accept(fd, NULL, NULL);
if (client == -1) {
int chanclient = accept(channelsock, NULL, NULL);
if (chanclient == -1) {
fprintf(stderr, "Skipping connection\n");
continue;
}
......@@ -97,11 +97,12 @@ int run_client(const char *socket_path)
// pselect multiple.
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(client, &readfds);
FD_SET(chanclient, &readfds);
FD_SET(displayfd, &readfds);
struct timespec timeout = {
.tv_sec = 0, .tv_nsec = 700000000L};
int maxfd = client > displayfd ? client : displayfd;
int maxfd = chanclient > displayfd ? chanclient
: displayfd;
int r = pselect(maxfd + 1, &readfds, NULL, NULL,
&timeout, NULL);
if (r == -1) {
......@@ -109,57 +110,91 @@ int run_client(const char *socket_path)
break;
}
fprintf(stderr, "Post select %d %d %d\n", r,
FD_ISSET(client, &readfds),
FD_ISSET(chanclient, &readfds),
FD_ISSET(displayfd, &readfds));
if (r == 0) {
const char *msg = "magic";
ssize_t nb = write(
client, msg, strlen(msg) + 1);
ssize_t nb = write(chanclient, msg,
strlen(msg) + 1);
if (nb == -1) {
fprintf(stderr, "Write failed, retrying anyway\n");
}
continue;
}
if (FD_ISSET(client, &readfds)) {
if (FD_ISSET(chanclient, &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));
struct muxheader header;
if (read(chanclient, &header,
sizeof(struct muxheader)) <
sizeof(struct muxheader)) {
fprintf(stderr, "FD header read failure: %s\n",
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));
char *tmpbuf = calloc(header.length, 1);
int nread = 0;
while (nread < header.length) {
int nr = read(chanclient,
tmpbuf + nread,
header.length - nread);
if (nr <= 0) {
break;
}
} else {
fprintf(stderr, "the other side shut down\n");
nread += nr;
}
if (nread < header.length) {
fprintf(stderr, "FD body read failure %ld/%ld: %s\n",
nread, header.length,
strerror(errno));
break;
}
fprintf(stderr, "read bytes: %d = %d\n", nread,
header.length);
int wc = iovec_write(displayfd, tmpbuf, nread,
NULL, NULL);
if (wc == -1) {
fprintf(stderr, "FD Write failure %ld: %s\n",
wc, strerror(errno));
break;
}
free(tmpbuf);
fprintf(stderr, "client done\n");
}
if (FD_ISSET(displayfd, &readfds)) {
fprintf(stderr, "displayfd isset\n");
int fdbuf[28];
int nfds = 28;
int rc = iovec_read(displayfd, buffer, maxmsg,
NULL, NULL);
fdbuf, &nfds);
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,
if (nfds > 0) {
for (int i = 0; i < nfds; i++) {
fprintf(stderr, "Got FD = %d\n",
fdbuf[i]);
identify_fd(fdbuf[i]);
}
}
struct muxheader header = {
.metadata = 0,
.length = rc};
if (write(chanclient, &header,
sizeof(header)) ==
-1) {
fprintf(stderr, "CS write header failure: %s\n",
strerror(errno));
break;
}
if (write(chanclient, buffer, rc) ==
-1) {
fprintf(stderr, "CS write body failure: %s\n",
strerror(errno));
break;
}
......@@ -174,7 +209,7 @@ int run_client(const char *socket_path)
fprintf(stderr, "Closing\n");
close(displayfd);
close(fd);
close(channelsock);
unlink(socket_path);
return EXIT_SUCCESS;
......
......@@ -84,7 +84,7 @@ int run_server(const char *socket_path, int app_argc, char *const app_argv[])
int status;
struct sockaddr_un saddr;
int fd;
int channelfd;
if (strlen(socket_path) >= sizeof(saddr.sun_path)) {
fprintf(stderr, "Socket path is too long and would be truncated: %s\n",
......@@ -94,15 +94,16 @@ int run_server(const char *socket_path, int app_argc, char *const app_argv[])
saddr.sun_family = AF_UNIX;
strncpy(saddr.sun_path, socket_path, sizeof(saddr.sun_path) - 1);
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd == -1) {
channelfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (channelfd == -1) {
fprintf(stderr, "Error creating socket: %s\n", strerror(errno));
return EXIT_FAILURE;
}
if (connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) {
if (connect(channelfd, (struct sockaddr *)&saddr, sizeof(saddr)) ==
-1) {
fprintf(stderr, "Error connecting socket: %s\n",
strerror(errno));
close(fd);
close(channelfd);
return EXIT_FAILURE;
}
......@@ -126,9 +127,10 @@ int run_server(const char *socket_path, int app_argc, char *const app_argv[])
break;
}
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
FD_SET(channelfd, &readfds);
FD_SET(client_socket, &readfds);
int maxfd = fd > client_socket ? fd : client_socket;
int maxfd = channelfd > client_socket ? channelfd
: client_socket;
int r = pselect(maxfd + 1, &readfds, NULL, NULL, &timeout,
NULL);
if (r < 0) {
......@@ -142,27 +144,42 @@ int run_server(const char *socket_path, int app_argc, char *const app_argv[])
} else {
fprintf(stderr, "%d are set\n", r);
}
if (FD_ISSET(fd, &readfds)) {
if (FD_ISSET(channelfd, &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,
struct muxheader header;
if (read(channelfd, &header, sizeof(struct muxheader)) <
sizeof(struct muxheader)) {
fprintf(stderr, "FD header read failure: %s\n",
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));
char *tmpbuf = calloc(header.length, 1);
int nread = 0;
while (nread < header.length) {
int nr = read(channelfd, tmpbuf + nread,
header.length - nread);
if (nr <= 0) {
break;
}
} else {
fprintf(stderr, "the other side shut down\n");
nread += nr;
}
if (nread < header.length) {
fprintf(stderr, "FD body read failure %ld/%ld: %s\n",
nread, header.length,
strerror(errno));
break;
}
fprintf(stderr, "Read from conn %d = %d bytes\n", nread,
header.length);
int wc = iovec_write(client_socket, tmpbuf, nread, NULL,
NULL);
if (wc == -1) {
fprintf(stderr, "FD Write failure %ld: %s\n",
wc, strerror(errno));
break;
}
free(tmpbuf);
}
if (FD_ISSET(client_socket, &readfds)) {
fprintf(stderr, "client socket isset\n");
......@@ -174,11 +191,17 @@ int run_server(const char *socket_path, int app_argc, char *const app_argv[])
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));
struct muxheader header = {
.metadata = 0, .length = rc};
if (write(channelfd, &header, sizeof(header)) ==
-1) {
fprintf(stderr, "CS write header failure: %s\n",
strerror(errno));
break;
}
if (write(channelfd, buffer, rc) == -1) {
fprintf(stderr, "CS write body failure: %s\n",
strerror(errno));
break;
}
} else {
......@@ -191,7 +214,7 @@ int run_server(const char *socket_path, int app_argc, char *const app_argv[])
break;
}
}
close(fd);
close(channelfd);
// todo: scope manipulation, to ensure all cleanups are done
waitpid(pid, &status, 0);
......
......@@ -23,14 +23,21 @@
* SOFTWARE.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.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))) ];
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;
......@@ -44,12 +51,33 @@ int iovec_read(int conn, char* buf, size_t buflen, int* fds, int* numfds) {
msg.msg_flags = 0;
ssize_t ret = recvmsg(conn, &msg, MSG_DONTWAIT);
// parse FDS
if (fds && numfds) {
int maxfds = *numfds;
*numfds = 0;
// Read cmsg
struct cmsghdr *header = CMSG_FIRSTHDR(&msg);
while (header) {
if (header->cmsg_level == SOL_SOCKET &&
header->cmsg_type == SCM_RIGHTS) {
int *data = (int *)CMSG_DATA(header);
int nf = (header->cmsg_len -
sizeof(struct cmsghdr)) /
sizeof(int);
for (int i = 0; i < nf && *numfds < maxfds;
i++) {
fds[(*numfds)++] = data[i];
}
}
header = CMSG_NXTHDR(&msg, header);
}
}
return ret;
}
int iovec_write(int conn, char* buf, size_t buflen, int* fds, int* numfds) {
// char cmsgdata[ (CMSG_LEN(28 * sizeof(int32_t))) ];
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;
......@@ -67,3 +95,28 @@ int iovec_write(int conn, char* buf, size_t buflen, int* fds, int* numfds) {
return ret;
}
void identify_fd(int fd)
{
struct stat fsdata;
memset(&fsdata, 0, sizeof(fsdata));
int ret = fstat(fd, &fsdata);
if (ret == -1) {
fprintf(stderr, "Failed to identify %d as a file: %s\n", fd,
strerror(errno));
} else {
fprintf(stderr, "The filedesc %d is a file, of size %d!\n", fd,
fsdata.st_size);
// then we can open the file, read the contents, create a mirror
// file, make diffs, and transfer them out of band!
// memmap & clone, assuming that the file will not be resized.
char *data = mmap(NULL, fsdata.st_size, PROT_READ, MAP_SHARED,
fd, 0);
if (!data) {
fprintf(stderr, "Mmap failed!\n");
}
munmap(data, fsdata.st_size);
}
}
......@@ -25,10 +25,18 @@
#ifndef WAYPIPE_UTIL_H
#define WAYPIPE_UTIL_H
#include <stdint.h>
#include <stddef.h>
#include <stdint.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);
int chan_write(int conn, char *buf, size_t buflen);
void identify_fd(int fd);
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);
struct muxheader {
int metadata;
int length;
};
#endif // WAYPIPE_UTIL_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment