damonp@daemon.UUCP (Damon Permezel) (08/22/84)
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@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;