Browse Source

Add code to create a socket pair and send filedescriptors

1.0.0
Georg Hopp 10 years ago
parent
commit
4562e816f0
  1. 5
      include/tr/socket.h
  2. 2
      src/Makefile.am
  3. 4
      src/socket_accept.c
  4. 55
      src/socket_get_fd.c
  5. 6
      src/socket_pair.c
  6. 52
      src/socket_send_fd.c
  7. 5
      src/tcp_socket.c

5
include/tr/socket.h

@ -66,6 +66,7 @@ TR_CLASS(TR_Socket) {
socklen_t addrlen;
int handle;
TR_SocketFin fin_state;
int fd_getter;
};
TR_INSTANCE_INIT(TR_Socket);
TR_CLASSVARS_DECL(TR_Socket) {};
@ -81,6 +82,7 @@ TR_CLASSVARS_DECL(TR_Socket) {};
#define TR_socketAddrlen(socket) ((socket)->addrlen)
#define TR_socketHandle(socket) ((socket)->handle)
#define TR_socketFinState(socket) ((socket)->fin_state)
#define TR_socketFdGetter(socket) ((socket)->fd_getter)
#define TR_socketFinRd(socket) \
((TR_socketFinState(socket) & TR_FIN_RD) == TR_FIN_RD)
#define TR_socketFinWr(socket) \
@ -118,7 +120,6 @@ TR_CLASSVARS_DECL(TR_Socket) {};
TR_CLASS(TR_TcpSocket) {
TR_EXTENDS(TR_Socket);
int listen;
int connected;
};
TR_INSTANCE_INIT(TR_TcpSocket);
@ -151,6 +152,8 @@ TR_TcpSocket TR_socketAccept(TR_TcpSocket);
(TR_socketInit((socket), NULL))
void TR_socketPair(TR_Socket[2], int);
void TR_socketSendFd(TR_Socket, int);
int TR_socketGetFd(TR_Socket);
#endif // __TR_SOCKET_H__

2
src/Makefile.am

@ -13,6 +13,8 @@ TRIO = stream.c \
socket_nonblock.c \
socket_close.c \
socket_pair.c \
socket_send_fd.c \
socket_get_fd.c \
socket_shutdown.c \
socket_shutdown_read.c \
socket_shutdown_write.c \

4
src/socket_accept.c

@ -42,7 +42,6 @@ TR_socketAccept(TR_TcpSocket this)
{
TR_Socket remote =
TR_new(TR_TcpSocket, TR_socketLog((TR_Socket)this), NULL, 0, 0);
//int flags;
remote->addrlen = ((TR_Socket)this)->addrlen;
remote->handle = accept(
@ -50,9 +49,6 @@ TR_socketAccept(TR_TcpSocket this)
&(remote->addr.info),
&(remote->addrlen));
//flags = fcntl(remote->handle, F_GETFL, 0);
//fcntl(remote->handle, F_SETFL, flags | O_NONBLOCK);
if (-1 == remote->handle) {
TR_delete(remote);
} else {

55
src/socket_get_fd.c

@ -0,0 +1,55 @@
/**
* \file
*
* \author Georg Hopp
*
* \copyright
* Copyright © 2014 Georg Hopp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h> // for errno
#include <unistd.h>
#include <fcntl.h>
#include "tr/socket.h"
#include "tr/logger.h"
int
TR_socketGetFd(TR_Socket this)
{
struct msghdr msg;
struct cmsghdr * cmsg;
char cmsgbuf[CMSG_SPACE(sizeof(int))];
int fd = 0;
memset(&msg, 0, sizeof(msg));
msg.msg_control = cmsgbuf;
msg.msg_controllen = sizeof(cmsgbuf);
if (0 > recvmsg(TR_socketHandle(this), &msg, 0)) {
return -1;
}
cmsg = CMSG_FIRSTHDR(&msg);
if (cmsg == NULL || cmsg->cmsg_type != SCM_RIGHTS) {
return -1;
}
memcpy(&fd, CMSG_DATA(cmsg), sizeof(int));
return fd;
}
// vim: set ts=4 sw=4:

6
src/socket_pair.c

@ -20,12 +20,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//#include <errno.h>
//#include <stdlib.h>
//#include <unistd.h>
//#include <stdio.h>
//#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

52
src/socket_send_fd.c

@ -0,0 +1,52 @@
/**
* \file
*
* \author Georg Hopp
*
* \copyright
* Copyright © 2014 Georg Hopp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h> // for errno
#include <unistd.h>
#include <fcntl.h>
#include "tr/socket.h"
#include "tr/logger.h"
void
TR_socketSendFd(TR_Socket this, int fd)
{
struct msghdr msg;
struct cmsghdr * cmsg;
char cmsgbuf[CMSG_SPACE(sizeof(int))];
memset(&msg, 0, sizeof(msg));
msg.msg_control = cmsgbuf;
msg.msg_controllen = sizeof(cmsgbuf); // necessary for CMSG_FIRSTHDR to
// return the correct value
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
msg.msg_controllen = cmsg->cmsg_len; // total size of all control blocks
sendmsg(TR_socketHandle(this), &msg, 0);
/* TODO error handling... */
}
// vim: set ts=4 sw=4:

5
src/tcp_socket.c

@ -41,10 +41,7 @@ tcpSocketCtor(void * _this, va_list * params)
TR_TcpSocket this = _this;
TR_PARENTCALL(TR_TcpSocket, _this, TR_Class, ctor, params);
TR_socketType((TR_Socket)this) = SOCK_STREAM;
this->listen = FALSE;
this->connected = FALSE;
return 0;
}
@ -66,7 +63,7 @@ tcpSocketBind(void * _this)
// error
return -1;
}
this->listen = TRUE;
((TR_Socket)this)->fd_getter = TRUE;
return 0;
}

Loading…
Cancel
Save