fcntl(F_SETOWN) problems
Damon Permezel
damonp at daemon.UUCP
Thu Aug 23 05:49:40 AEST 1984
Index: /sys/sys/kern_descrip.c 4.2BSD
Description:
The man page for 'fcntl' states that, for the F_GETOWN and F_GETOWN
options, process groups are indicated with negative values, and
process ids are indicated with positive values.
If a fcntl is performed on a socket, the value is placed unmodified
in the so_pgrp field of the socket structure.
The routine sohasoutofband() assumes that if so_pgrp is positive,
it is a process group, and if negative, a process ID.
If one does an ioctl(SIOCSPGRP) on a socket, the soo_ioctl() routine
treats so_pgrp similar the sohasoutofband().
This problem was noticed when trying to send out-of-band data in the
UNIX domain on a stream socket. sohasoutofband() delivered the signal
to the wrong process(es).
There will be a companion bug report soon describing how you can
get OOB data to work in the UNIX domain!
Repeat-By:
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <sys/ioctl.h>
main() {
static struct sockaddr sock;
static struct sockaddr sock2;
int s;
int socklen, stuff, pgrp, res;
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("socket");
exit(1);
}
strcpy(sock.sa_data, "testsock");
socklen = sizeof(sock);
unlink("testsock");
if (bind(s, &sock, socklen) < 0) {
perror("bind");
exit(1);
}
pgrp = getpgrp(); /* get our process group */
res = fcntl(s, F_SETOWN, -pgrp); /* set to process group */
if (res < 0) {
perror("fcntl");
exit(3);
}
res = ioctl(s, SIOCGPGRP, &stuff);
if (res < 0) {
perror("ioctl");
exit(4);
}
printf("process group set to %d, but comes back %d\n", pgrp, stuff);
}
Fix:
I changed the routines fsetown() and fgetown() to negate the
negated process group ID, thus rendering it positive, prior to stuffing
it in so_pgrp. Diffs follow. Line numbers will be off.
4a5,21
> * Revision 1.4 84/08/21 03:15:37 damonp
> * Since the fcntl man page asserts that process groups for the
> * F_SETOWN and F_GETOWN options are <0, and soo_ioctl(SIOCSPGRP)
> * and sohasoutofband() both agree that so_pgrp is >0, it was necessary
> * to negate it in fsetown() and fgetown().
> * -dap at tek
> *
202c219
< *valuep = ((struct socket *)fp->f_data)->so_pgrp;
---
> *valuep = -((struct socket *)fp->f_data)->so_pgrp;
218c235
< ((struct socket *)fp->f_data)->so_pgrp = value;
---
> ((struct socket *)fp->f_data)->so_pgrp = -value;
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list