View | Details | Raw Unified | Return to bug 18940
Collapse All | Expand All

(-)linux_file.c (-47 / +3 lines)
Lines 199-210 Link Here
199
    } */ fcntl_args; 
199
    } */ fcntl_args; 
200
    struct linux_flock linux_flock;
200
    struct linux_flock linux_flock;
201
    struct flock *bsd_flock;
201
    struct flock *bsd_flock;
202
    struct filedesc *fdp;
203
    struct file *fp;
204
    struct vnode *vp;
205
    long pgid;
206
    struct pgrp *pgrp;
207
    struct tty *tp;
208
    caddr_t sg;
202
    caddr_t sg;
209
    dev_t dev;
203
    dev_t dev;
210
204
Lines 289-335 Link Here
289
283
290
    case LINUX_F_SETOWN:
284
    case LINUX_F_SETOWN:
291
    case LINUX_F_GETOWN:
285
    case LINUX_F_GETOWN:
292
	/*
286
       fcntl_args.cmd = args->cmd == LINUX_F_SETOWN ? F_SETOWN : F_GETOWN;
293
	 * We need to route around the normal fcntl() for these calls,
287
       fcntl_args.arg = args->arg;
294
	 * since it uses TIOC{G,S}PGRP, which is too restrictive for
288
       return fcntl(p, &fcntl_args); 
295
	 * Linux F_{G,S}ETOWN semantics. For sockets, this problem
296
	 * does not exist.
297
	 */
298
	fdp = p->p_fd;
299
	if ((u_int)args->fd >= fdp->fd_nfiles ||
300
		(fp = fdp->fd_ofiles[args->fd]) == NULL)
301
	    return EBADF;
302
	if (fp->f_type == DTYPE_SOCKET) {
303
	    fcntl_args.cmd = args->cmd == LINUX_F_SETOWN ? F_SETOWN : F_GETOWN;
304
    	    fcntl_args.arg = args->arg;
305
	    return fcntl(p, &fcntl_args); 
306
	}
307
	vp = (struct vnode *)fp->f_data;
308
	dev = vn_todev(vp);
309
	if (dev == NODEV)
310
	    return EINVAL;
311
	if (!(devsw(dev)->d_flags & D_TTY))
312
	    return EINVAL;
313
	tp = dev->si_tty;
314
	if (!tp)
315
	    return EINVAL;
316
	if (args->cmd == LINUX_F_GETOWN) {
317
	    p->p_retval[0] = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
318
	    return 0;
319
	}
320
	if ((long)args->arg <= 0) {
321
	    pgid = -(long)args->arg;
322
	} else {
323
	    struct proc *p1 = pfind((long)args->arg);
324
	    if (p1 == 0)
325
		return (ESRCH);
326
	    pgid = (long)p1->p_pgrp->pg_id;
327
	}
328
	pgrp = pgfind(pgid);
329
	if (pgrp == NULL || pgrp->pg_session != p->p_session)
330
	    return EPERM;
331
	tp->t_pgrp = pgrp;
332
	return 0;
333
    }
289
    }
334
    return EINVAL;
290
    return EINVAL;
335
}
291
}

Return to bug 18940