Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Source/CFRuntime.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ GS_PRIVATE void CFNumberInitialize (void);
GS_PRIVATE void CFNumberFormatterInitialize (void);
GS_PRIVATE void CFRunLoopInitialize (void);
GS_PRIVATE void CFSetInitialize (void);
GS_PRIVATE void CFSocketInitialize (void);
GS_PRIVATE void CFStreamInitialize (void);
GS_PRIVATE void CFStringInitialize (void);
GS_PRIVATE void CFConstantStringInitialize (void);
Expand Down Expand Up @@ -530,6 +531,7 @@ CFInitialize (void)
CFNumberInitialize ();
CFNumberFormatterInitialize ();
CFSetInitialize ();
CFSocketInitialize ();
CFStreamInitialize ();
CFStringInitialize ();
CFConstantStringInitialize (); /* must be after CFStringIntialize () */
Expand Down
22 changes: 11 additions & 11 deletions Source/CFSocket.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ CFSocketCopyAddress (CFSocketRef s)
if (s->_address == NULL)
{
struct sockaddr addr;
socklen_t addrlen;
socklen_t addrlen = sizeof (addr);
getsockname (s->_socket, &addr, &addrlen);
s->_address = CFDataCreate (CFGetAllocator (s), (const UInt8*)&addr,
(CFIndex)addrlen);
Expand All @@ -394,18 +394,18 @@ CFSocketCopyPeerAddress (CFSocketRef s)
CFDataRef ret = NULL;

GSMutexLock (&s->_lock);
if (s->_address == NULL)
if (s->_peerAddress == NULL)
{
struct sockaddr addr;
socklen_t addrlen;
socklen_t addrlen = sizeof (addr);
getpeername (s->_socket, &addr, &addrlen);
s->_address = CFDataCreate (CFGetAllocator (s), (const UInt8*)&addr,
(CFIndex)addrlen);
s->_peerAddress = CFDataCreate (CFGetAllocator (s), (const UInt8*)&addr,
(CFIndex)addrlen);
}
if (s->_address != NULL)
ret = CFRetain (s->_address);
if (s->_peerAddress != NULL)
ret = CFRetain (s->_peerAddress);
GSMutexUnlock (&s->_lock);

return ret;
}

Expand Down Expand Up @@ -600,15 +600,15 @@ CFSocketSendData (CFSocketRef s, CFDataRef address, CFDataRef data,
addr = (struct sockaddr*) CFDataGetBytePtr(address);
len = CFDataGetLength(address);

err = sendto(s->_socket, CFDataGetBytePtr(data), 0,
CFDataGetLength(data), addr, len);
err = sendto(s->_socket, CFDataGetBytePtr(data),
CFDataGetLength(data), 0, addr, len);
}
else
{
err = send(s->_socket, CFDataGetBytePtr(data),
CFDataGetLength(data), 0);
}
if (err == 0)
if (err >= 0)
return kCFSocketSuccess;
else if (errno == EAGAIN || errno == EWOULDBLOCK)
return kCFSocketTimeout;
Expand Down
Empty file added Tests/CFSocket/TestInfo
Empty file.
68 changes: 68 additions & 0 deletions Tests/CFSocket/general.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include "CoreFoundation/CFRunLoop.h"
#include "CoreFoundation/CFSocket.h"
#include "CoreFoundation/CFData.h"
#include "../CFTesting.h"

#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <string.h>
#include <unistd.h>

/* CFSocket datagram send and address queries over loopback UDP. */

int main (void)
{
int rfd, sfd;
struct sockaddr_in raddr;
socklen_t rlen;
struct timeval tv;
CFSocketRef cs;
CFDataRef addrData, payload, local, peer;
CFSocketError serr;
char buf[16];
ssize_t n;

/* Receiver bound to a loopback ephemeral port. */
rfd = socket (AF_INET, SOCK_DGRAM, 0);
memset (&raddr, 0, sizeof (raddr));
raddr.sin_family = AF_INET;
raddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
bind (rfd, (struct sockaddr *) &raddr, sizeof (raddr));
rlen = sizeof (raddr);
getsockname (rfd, (struct sockaddr *) &raddr, &rlen);
tv.tv_sec = 2; /* do not hang if no datagram arrives */
tv.tv_usec = 0;
setsockopt (rfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof (tv));

sfd = socket (AF_INET, SOCK_DGRAM, 0);
cs = CFSocketCreateWithNative (NULL, sfd, 0, NULL, NULL);
PASS_CF(cs != NULL, "CFSocket created from a native UDP socket.");

/* Send to an explicit address (the sendto() path). */
addrData = CFDataCreate (NULL, (const UInt8 *) &raddr, rlen);
payload = CFDataCreate (NULL, (const UInt8 *) "hello", 5);
serr = CFSocketSendData (cs, addrData, payload, 1.0);
PASS_CF(serr == kCFSocketSuccess, "CFSocketSendData reports success.");
memset (buf, 0, sizeof (buf));
n = recv (rfd, buf, sizeof (buf), 0);
PASS_CF(n == 5 && memcmp (buf, "hello", 5) == 0,
"The 5-byte datagram was actually transmitted and received.");

/* Connect so the local and peer addresses are well-defined. */
connect (sfd, (struct sockaddr *) &raddr, rlen);

local = CFSocketCopyAddress (cs);
PASS_CF(local != NULL
&& CFDataGetLength (local) == (CFIndex) sizeof (struct sockaddr_in),
"CFSocketCopyAddress returns a correctly-sized address.");

peer = CFSocketCopyPeerAddress (cs);
PASS_CF(peer != NULL
&& CFDataGetLength (peer) == (CFIndex) sizeof (struct sockaddr_in)
&& ((const struct sockaddr_in *) CFDataGetBytePtr (peer))->sin_port
== raddr.sin_port,
"CFSocketCopyPeerAddress returns the peer address.");

return 0;
}
Loading