* [PATCH] Have sigpoll and sigio band field match glibc for n64
@ 2007-03-09 19:46 Peter Watkins
2007-03-09 19:46 ` Peter Watkins
2007-03-10 13:24 ` Ralf Baechle
0 siblings, 2 replies; 7+ messages in thread
From: Peter Watkins @ 2007-03-09 19:46 UTC (permalink / raw)
To: linux-mips, ralf
Hello,
The siginfo field si_fd is incorrect on n64 because the band field does not match glibc.
The patch is in the next mail. Tested on Malta and Sicortex. Below is how to reproduce the problem.
run ./sigio on mips64 testmachine
on another machine, telnet testmachine 8888
Correct output:
gcc -o sigio sigio.c -mabi=n32
./sigio
fd 3 sock 4
sigio : fd 1065
sigio : fd 4
sigio : fd 4
sigio : fd 4
sigio : fd 4
sigio : fd 4
sigio : fd 4
...
Incorrect output:
gcc -o sigio sigio.c -mabi=64
./sigio
fd 3 sock 4
sigio : fd 1065
sigio : fd 0
sigio : fd 0
sigio : fd 0
sigio : fd 0
sigio : fd 0
Test program (from Andrew Gierth)
#define _GNU_SOURCE 1
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdarg.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#define TCP_PORT 8888
/* This example uses SIGIO and SIGURG on a TCP socket for convenience. */
/* In practice, SIGIO is almost useless on stream sockets, because it */
/* gets generated by far too many different events. */
/* To test, just telnet to port 8888. Use telnet's 'synch' command to */
/* generate OOB data for SIGURG. */
/* The program simply echos data in hex, bracketing all 'urgent' data */
/* in []. */
/* I say again: USE SIGIO ON STREAM SOCKETS ONLY AS A LAST RESORT. */
/* handle cruft */
#if EWOULDBLOCK == EAGAIN
# define IS_WOULDBLOCK(err) ((err)==EAGAIN)
#else
# define IS_WOULDBLOCK(err) (((err)==EAGAIN)||((err)==EWOULDBLOCK))
#endif
/* useful functions */
void errexit(const char *msg)
{
perror(msg);
exit(1);
}
/* this is done this way in an attempt to be safe in a signal handler. */
void complain(const char *msg,...)
{
va_list va;
char buf[1024];
va_start(va,msg);
vsprintf(buf, msg, va);
va_end(va);
write(STDERR_FILENO, buf, strlen(buf));
}
/* might need fcntl(F_SETFL), or ioctl(FIONBIO) */
/* Posix.1g says fcntl */
/* NEVER, EVER USE O_NDELAY HERE */
#ifdef O_NONBLOCK
int set_nonblock(int fd)
{
int flags = fcntl(fd, F_GETFL, 0);
if (flags == -1)
return -1;
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
#else
int set_nonblock(int fd)
{
int yes = 1;
return ioctl(fd, FIONBIO, &yes);
}
#endif
/* might need fcntl(F_SETOWN), or ioctl(FIOSETOWN), or ioctl(SIOCSPGRP) */
/* Posix.1g says fcntl */
#ifdef F_SETOWN
int set_owner(int fd)
{
return fcntl(fd, F_SETOWN, getpid());
}
#else
int set_owner(int fd)
{
pid_t pid = getpid();
return ioctl(fd, FIOSETOWN, &pid);
}
#endif
/* might need fcntl(F_SETFL), or ioctl(FIOASYNC) */
/* Posix.1g says fcntl */
/* DONT use I_SETSIG unless portability isn't an issue - remember, */
/* SOCKETS ARE NOT STREAMS! */
#ifdef O_ASYNC
int set_async(int fd)
{
int flags = fcntl(fd, F_GETFL, 0);
if (flags == -1)
return -1;
return fcntl(fd, F_SETFL, flags | O_ASYNC);
}
#else
int set_async(int fd)
{
int yes = 1;
return ioctl(fd, FIOASYNC, &yes);
}
#endif
int sockatmark(int sock)
{
int flag = 0;
if (ioctl(sock, SIOCATMARK, &flag) < 0)
return -1;
return (flag != 0) ? 1 : 0;
}
/* Ought to be able to do this with SIOCATMARK, but on my FreeBSD system */
/* it wasn't behaving in any sort of consistent fashion. */
int urgent_pending(int sock)
{
struct timeval tv;
fd_set fds;
FD_ZERO(&fds);
FD_SET(sock,&fds);
tv.tv_sec = 0;
tv.tv_usec = 0;
return select(sock+1,NULL,NULL,&fds,&tv);
}
/*-------------------------------------------------------------------------*/
int sock;
sigset_t sigio_set;
sigset_t sigurg_set;
sigset_t empty_set;
volatile sig_atomic_t urgmode = 0;
volatile sig_atomic_t sigiocount = 0;
volatile sig_atomic_t sigurgcount = 0;
void sigio_handler(int sig, struct siginfo *info, void *data)
{
char inbuf[64];
char outbuf[4];
int i,rc,flag;
sigset_t sigs;
sigiocount++;
complain("sigio : fd %d \n", info->si_fd);
for (;;)
{
rc = read(sock, inbuf, sizeof(inbuf));
if (rc < 0 && IS_WOULDBLOCK(errno))
return;
if (rc < 0)
{
complain("error on read: %d (%s)\n", errno, strerror(errno));
_exit(1);
}
if (rc == 0)
{
complain("Done.\n");
complain("Total SIGIOs : %ld\n", (long) sigiocount);
complain("Total SIGURGs: %ld\n", (long) sigurgcount);
_exit(0);
}
for (i = 0; i < rc; i++)
{
outbuf[0] = ' ';
outbuf[1] = "0123456789ABCDEF"[(inbuf[i] >> 4) & 0x0F];
outbuf[2] = "0123456789ABCDEF"[inbuf[i] & 0x0F];
write(sock, outbuf, 3);
}
sigprocmask(SIG_BLOCK, &sigurg_set, &sigs);
if (urgmode && !urgent_pending(sock))
{
write(sock, "]", 1);
urgmode = 0;
}
sigprocmask(SIG_SETMASK, &sigs, NULL);
}
}
void sigurg_handler(int sig)
{
sigurgcount++;
urgmode = 1;
write(sock, " [", 2);
}
main()
{
struct sigaction sa;
struct sockaddr_in addr;
int addrlen = sizeof(addr);
int fd = socket(AF_INET, SOCK_STREAM, 0);
int yes = 1;
if (fd < 0)
errexit("socket");
sigemptyset(&empty_set);
sigemptyset(&sigio_set);
sigaddset(&sigio_set,SIGIO);
sigemptyset(&sigurg_set);
sigaddset(&sigurg_set,SIGURG);
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0)
errexit("setsockopt");
/* set this in the listen socket; it will be inherited. */
if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &yes, sizeof(int)) < 0)
errexit("setsockopt");
addr.sin_family = AF_INET;
addr.sin_port = htons(TCP_PORT);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(fd, (struct sockaddr *) &addr, addrlen) < 0)
errexit("bind");
if (listen(fd,5) < 0)
errexit("listen");
sock = accept(fd, (struct sockaddr *) &addr, &addrlen);
if (sock < 0)
errexit("accept");
printf("fd %d sock %d\n", fd, sock);
close(fd);
/* block SIGIO and SIGURG while we set everything up. */
sigprocmask(SIG_BLOCK, &sigio_set, NULL);
sigprocmask(SIG_BLOCK, &sigurg_set, NULL);
if (set_nonblock(sock) < 0)
errexit("set_nonblock");
if (set_owner(sock) < 0)
errexit("set_owner");
if (set_async(sock) < 0)
errexit("set_async");
sa.sa_handler = sigio_handler;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sigaction(SIGIO, &sa, NULL);
sa.sa_handler = sigurg_handler;
sa.sa_flags = 0;
sa.sa_mask = sigio_set;
sigaction(SIGURG, &sa, NULL);
int ret;
ret = fcntl(sock, F_SETSIG, SIGIO);
if (ret == -1) {
printf("cannot setsig: %s\n", strerror(errno));
errexit("setsig");
}
/* data may have arrived while we were setting up, so generate */
/* SIGIO now. */
raise(SIGIO);
/* unblock everything, then pause. */
sigprocmask(SIG_SETMASK, &empty_set, NULL);
for(;;)
pause();
/*NOTREACHED*/
return 0;
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] Have sigpoll and sigio band field match glibc for n64.
2007-03-09 19:46 [PATCH] Have sigpoll and sigio band field match glibc for n64 Peter Watkins
@ 2007-03-09 19:46 ` Peter Watkins
2007-03-10 13:24 ` Ralf Baechle
1 sibling, 0 replies; 7+ messages in thread
From: Peter Watkins @ 2007-03-09 19:46 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Peter Watkins
From: Peter Watkins <pwatkins@gsrv020.sicortex.com>
---
include/asm-mips/siginfo.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/asm-mips/siginfo.h b/include/asm-mips/siginfo.h
index 2e32949..37a0e1f 100644
--- a/include/asm-mips/siginfo.h
+++ b/include/asm-mips/siginfo.h
@@ -32,6 +32,8 @@ #ifdef CONFIG_64BIT
#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
#endif
+#define __ARCH_SI_BAND_T int
+
#include <asm-generic/siginfo.h>
typedef struct siginfo {
--
1.4.2.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] Have sigpoll and sigio band field match glibc for n64
2007-03-09 19:46 [PATCH] Have sigpoll and sigio band field match glibc for n64 Peter Watkins
2007-03-09 19:46 ` Peter Watkins
@ 2007-03-10 13:24 ` Ralf Baechle
2007-03-13 14:19 ` Daniel Jacobowitz
1 sibling, 1 reply; 7+ messages in thread
From: Ralf Baechle @ 2007-03-10 13:24 UTC (permalink / raw)
To: Peter Watkins; +Cc: linux-mips
On Fri, Mar 09, 2007 at 02:46:25PM -0500, Peter Watkins wrote:
> The siginfo field si_fd is incorrect on n64 because the band field does
> not match glibc.
Susv3 says:
[...]
The <signal.h> header shall define the siginfo_t type as a structure that
includes at least the following members:
[...]
long si_band Band event for SIGPOLL.
[...]
So the kernel is right, glibc is wrong I'd say ...
Ralf
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Have sigpoll and sigio band field match glibc for n64
2007-03-10 13:24 ` Ralf Baechle
@ 2007-03-13 14:19 ` Daniel Jacobowitz
2007-03-13 16:41 ` Ralf Baechle
0 siblings, 1 reply; 7+ messages in thread
From: Daniel Jacobowitz @ 2007-03-13 14:19 UTC (permalink / raw)
To: Ralf Baechle; +Cc: Peter Watkins, linux-mips
On Sat, Mar 10, 2007 at 01:24:24PM +0000, Ralf Baechle wrote:
> On Fri, Mar 09, 2007 at 02:46:25PM -0500, Peter Watkins wrote:
>
> > The siginfo field si_fd is incorrect on n64 because the band field does
> > not match glibc.
>
> Susv3 says:
>
> [...]
> The <signal.h> header shall define the siginfo_t type as a structure that
> includes at least the following members:
>
> [...]
> long si_band Band event for SIGPOLL.
> [...]
>
> So the kernel is right, glibc is wrong I'd say ...
This will break the ABI only for uses of si_band and si_fd, and only
on n64. Anyone see a reason why I shouldn't change glibc?
Ralf, as I mentioned on IRC, I've got bigger worries about siginfo.
Shouldn't n32 be using the same siginfo as o32? It's got pointers in it.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Have sigpoll and sigio band field match glibc for n64
2007-03-13 14:19 ` Daniel Jacobowitz
@ 2007-03-13 16:41 ` Ralf Baechle
2007-03-14 17:48 ` Daniel Jacobowitz
0 siblings, 1 reply; 7+ messages in thread
From: Ralf Baechle @ 2007-03-13 16:41 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Peter Watkins, linux-mips
On Tue, Mar 13, 2007 at 10:19:51AM -0400, Daniel Jacobowitz wrote:
> This will break the ABI only for uses of si_band and si_fd, and only
> on n64. Anyone see a reason why I shouldn't change glibc?
>
> Ralf, as I mentioned on IRC, I've got bigger worries about siginfo.
> Shouldn't n32 be using the same siginfo as o32? It's got pointers in it.
Yes, you're right. Will you cook up a patch?
Ralf
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Have sigpoll and sigio band field match glibc for n64
2007-03-13 16:41 ` Ralf Baechle
@ 2007-03-14 17:48 ` Daniel Jacobowitz
2007-03-14 17:56 ` Ralf Baechle
0 siblings, 1 reply; 7+ messages in thread
From: Daniel Jacobowitz @ 2007-03-14 17:48 UTC (permalink / raw)
To: Ralf Baechle; +Cc: Peter Watkins, linux-mips
On Tue, Mar 13, 2007 at 04:41:07PM +0000, Ralf Baechle wrote:
> On Tue, Mar 13, 2007 at 10:19:51AM -0400, Daniel Jacobowitz wrote:
>
> > This will break the ABI only for uses of si_band and si_fd, and only
> > on n64. Anyone see a reason why I shouldn't change glibc?
> >
> > Ralf, as I mentioned on IRC, I've got bigger worries about siginfo.
> > Shouldn't n32 be using the same siginfo as o32? It's got pointers in it.
>
> Yes, you're right. Will you cook up a patch?
I won't have time any time soon - my MIPS board isn't hooked up.
If no one has by the time I get around to it next, though, I'll try.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Have sigpoll and sigio band field match glibc for n64
2007-03-14 17:48 ` Daniel Jacobowitz
@ 2007-03-14 17:56 ` Ralf Baechle
0 siblings, 0 replies; 7+ messages in thread
From: Ralf Baechle @ 2007-03-14 17:56 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Peter Watkins, linux-mips
On Wed, Mar 14, 2007 at 01:48:54PM -0400, Daniel Jacobowitz wrote:
> I won't have time any time soon - my MIPS board isn't hooked up.
> If no one has by the time I get around to it next, though, I'll try.
Oh well, it's reasonably straight forward, so I guess I can try to fix
that but I don't have an N32 setup for testing ...
Ralf
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2007-03-14 17:58 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-09 19:46 [PATCH] Have sigpoll and sigio band field match glibc for n64 Peter Watkins
2007-03-09 19:46 ` Peter Watkins
2007-03-10 13:24 ` Ralf Baechle
2007-03-13 14:19 ` Daniel Jacobowitz
2007-03-13 16:41 ` Ralf Baechle
2007-03-14 17:48 ` Daniel Jacobowitz
2007-03-14 17:56 ` Ralf Baechle
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox