Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
157 user(s) are online (139 user(s) are browsing Forums)

Members: 0
Guests: 157

more...

Support us!

Headlines

 
  Register To Post  

bsdsocket and exec signals [NEW PROBLEM]
Just can't stay away
Just can't stay away


See User information
Argh!...

I need to be able to do asynchronous io with sockets using exec signals, but I can't get it to work. The ISocket->SocketBaseTags() should set up bsdlibrary to send exec signals, but the signal never arrives. If you remove the IExec->Wait() statement, the code works of course...

Help!

Quote:

#define DATA1 "test string 1"
#define DATA2 "test string 2"

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>

#include <proto/exec.h>
#include <proto/bsdsocket.h>

/*
* set_nonblocking(): Set a fd into nonblocking mode.
*/
static int set_nonblocking(int fd)
{
int val;

if((val = fcntl(fd, F_GETFL, 0)) == -1) return -1;
if (!(val & O_NONBLOCK)) {
val |= O_NONBLOCK;
fcntl(fd, F_SETFL, val);
}
return 0;
}

/*
* set_blocking(): Set a fd into blocking mode.
*/
static int set_blocking(int fd)
{
int val;

if((val = fcntl(fd, F_GETFL, 0)) == -1) return -1;
if (val & O_NONBLOCK) {
val &= ~O_NONBLOCK;
fcntl(fd, F_SETFL, val);
}
return 0;
}

/*
* __socketpair_tcp(): Create a socket pipe.
*/
int __socketpair_tcp(int fd[2])
{
int listener;
struct sockaddr sock;
socklen_t socklen = sizeof(sock);
int len = socklen;
int one = 1;
int connect_done = 0;

fd[0] = fd[1] = listener = -1;

memset(&sock, 0, sizeof(sock));

if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
goto failed;
}

setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));

if (listen(listener, 1) != 0) {
goto failed;
}

if (getsockname(listener, &sock, (socklen_t *) &socklen) != 0) {
goto failed;
}

if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
goto failed;
}

setsockopt(fd[1], SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));

set_nonblocking(fd[1]);

if (connect(fd[1], (struct sockaddr *) &sock, sizeof(sock)) == -1) {
if (errno != EINPROGRESS) {
goto failed;
}
connect_done = 1;
} else {
connect_done = 1;
}

if ((fd[0] = accept(listener, &sock, (socklen_t *) &len)) == -1) {
goto failed;
}

setsockopt(fd[0], SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));

close(listener); listener = -1;
if (connect_done == 0) {
if (connect(fd[1], (struct sockaddr *) &sock, sizeof(sock)) != 0) {
goto failed;
}
}

set_blocking(fd[1]);

/* all OK! */
return 0;

failed:
printf("socketpair failed!\n");
if (fd[0] != -1) close(fd[0]);
if (fd[1] != -1) close(fd[1]);
if (listener != -1) close(listener);
return -1;
}

main()
{
int sockets[2], child;
char buf[1024];

/* Get the socket pair */
if (__socketpair_tcp(sockets) < 0) {
printf("error %d on socketpair\n", errno);
exit(1);
}
BYTE socketSignal = IExec->AllocSignal(-1);
uint32 socketSignalMask = 1 << socketSignal;

printf("socketSignalMask = 0x%x\n", socketSignalMask);

ISocket->SocketBaseTags (SBTM_SETVAL(SBTC_SIGEVENTMASK), socketSignalMask, TAG_END);

/* write message to child */
if (write(sockets[1], DATA1, sizeof(DATA1)) < 0) {
printf("error %d writing socket\n", errno);
exit(1);
}

/* send message to parent */
if (write(sockets[0], DATA2, sizeof(DATA1)) < 0) {
printf("error %d writing socket\n", errno);
exit(1);
}

IExec->Wait(socketSignalMask);

/* get message from parent */
if (read(sockets[0], buf, sizeof(buf)) < 0) {
printf("error %d reading socket\n", errno);
exit(1);
}
printf("-->%s\n", buf);

IExec->FreeSignal (socketSignal);

/* finished */
close(sockets[0]);
close(sockets[1]);
}


(Note, that this is a test scenario, so don't get too hung up on the code actually making any practical sense. It is just the same thread reading and writing to/from the same socket pair.)


Edited by alfkil on 2010/11/8 18:55:39
Go to top
Re: bsdsocket and exec signals
Just popping in
Just popping in


See User information
@alfkil

Your code is missing the setsockopt() call to tell the TCP/IP stack in which events you are interested in. Without that it has to assume you are interested in nothing and hence will never Signal() your application. Refer to the GetSocketEvents docs for more details.

Go to top
Re: bsdsocket and exec signals
Just popping in
Just popping in


See User information
@alfkil

Niggly. Second sizeof(DATA1) should be DATA2.

Go to top
Re: bsdsocket and exec signals
Just can't stay away
Just can't stay away


See User information
@tboeckel

Thanks for the info! Still, I don't quite understand how it is supposed to work:
The "getsockopt()" entry in the docs don't mention anything about SO_EVENTMASK as mentioned in the GetSocketEvents() entry, which makes me a little confused. Could you give an example, maybe??

EDIT: I tried inserting the following line, but it changes nothing:

Quote:
setsockopt(sockets[0], SOL_SOCKET, SO_EVENTMASK, (const void *)&socketSignalMask, sizeof(socketSignalMask));

Go to top
Re: bsdsocket and exec signals
Just popping in
Just popping in


See User information
@alfkil

Quote:
ULONG temp = FD_ACCEPT | FD_CONNECT | FD_READ | FD_WRITE | FD_ERROR;
setsockopt(socket, SOL_SOCKET, SO_EVENTMASK, &temp, sizeof(temp));

Go to top
Re: bsdsocket and exec signals
Just can't stay away
Just can't stay away


See User information
@tboeckel

Ahh... Me dumbass, you smart

Go to top
Re: bsdsocket and exec signals
Just can't stay away
Just can't stay away


See User information
EDITED:
Maybe someone can help me with this one also:

I'm not sure how to query the connection for data. Code hangs on both read() and IExec->Wait():


Quote:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <netdb.h>

#include <proto/exec.h>
#include <proto/bsdsocket.h>

#define MAX_BUF 100

int main(int argc, char* argv[])
{
int sockd;
int count;
struct sockaddr_in serv_name;
char buf[MAX_BUF];
int status;

/* create a socket */
sockd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockd == -1)
{
perror("Socket creation");
exit(1);
}

/* server address */
serv_name.sin_family = AF_INET;
struct hostent *hent = gethostbyname("www.google.com");
if (!hent)
{
perror ("gethostbyname failed");
exit(-1);
}
if (hent->h_addrtype != AF_INET)
{
perror("Unknown address type");
exit(-1);
}

printf("hostname = %s\n", hent->h_name);

//What is supposed to happen here???
//serv_name.sin_addr.s_addr = inet_addr(hent->h_addr_list[0]);
memcpy (&(serv_name.sin_addr.s_addr), hent->h_addr, hent->h_length);
serv_name.sin_port = htons (12345);

/* connect to the server */
status = connect(sockd, (struct sockaddr*)&serv_name, sizeof(serv_name));
if (status == -1)
{
perror("Connection error");
exit(1);
}
printf("connected to server\n");

BYTE socketSignal = IExec->AllocSignal(-1);
uint32 socketSignalMask = 1 << socketSignal;

printf("socketSignalMask = 0x%x\n", socketSignalMask);

ISocket->SocketBaseTags (SBTM_SETVAL(SBTC_SIGEVENTMASK), socketSignalMask, TAG_END);

ULONG temp = FD_ACCEPT | FD_CONNECT | FD_READ | FD_WRITE | FD_ERROR;
setsockopt(sockd, SOL_SOCKET, SO_EVENTMASK, &temp, sizeof(temp));

IExec->Wait (socketSignalMask|SIGBREAKF_CTRL_C);
printf("signal received\n");

count = read(sockd, buf, MAX_BUF);
write(1, buf, count);

close(sockd);

IExec->FreeSignal(socketSignal);
return 0;
}


Edited by alfkil on 2010/11/8 17:16:02
Go to top

  Register To Post

 




Currently Active Users Viewing This Thread: 1 ( 0 members and 1 Anonymous Users )




Powered by XOOPS 2.0 © 2001-2024 The XOOPS Project