|
1 | | -/* $NetBSD: kern_descrip.c,v 1.106 2003/03/22 10:35:01 dsl Exp $ */ |
| 1 | +/* $NetBSD: kern_descrip.c,v 1.107 2003/03/22 10:39:47 dsl Exp $ */ |
2 | 2 |
|
3 | 3 | /* |
4 | 4 | * Copyright (c) 1982, 1986, 1989, 1991, 1993 |
|
41 | 41 | */ |
42 | 42 |
|
43 | 43 | #include <sys/cdefs.h> |
44 | | -__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.106 2003/03/22 10:35:01 dsl Exp $"); |
| 44 | +__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.107 2003/03/22 10:39:47 dsl Exp $"); |
45 | 45 |
|
46 | 46 | #include <sys/param.h> |
47 | 47 | #include <sys/systm.h> |
@@ -329,20 +329,30 @@ sys_fcntl(struct lwp *l, void *v, register_t *retval) |
329 | 329 | tmp = FFLAGS((long)SCARG(uap, arg)) & FCNTLFLAGS; |
330 | 330 | error = (*fp->f_ops->fo_fcntl)(fp, F_SETFL, &tmp, p); |
331 | 331 | if (error) |
332 | | - goto out; |
333 | | - fp->f_flag &= ~FCNTLFLAGS; |
334 | | - fp->f_flag |= tmp; |
335 | | - tmp = fp->f_flag & FNONBLOCK; |
336 | | - error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, &tmp, p); |
337 | | - if (error) |
338 | | - goto out; |
339 | | - tmp = fp->f_flag & FASYNC; |
340 | | - error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, &tmp, p); |
341 | | - if (error == 0) |
342 | | - goto out; |
343 | | - fp->f_flag &= ~FNONBLOCK; |
344 | | - tmp = 0; |
345 | | - (void) (*fp->f_ops->fo_ioctl)(fp, FIONBIO, &tmp, p); |
| 332 | + break; |
| 333 | + i = tmp ^ fp->f_flag; |
| 334 | + if (i & FNONBLOCK) { |
| 335 | + int fl = tmp & FNONBLOCK; |
| 336 | + error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, &fl, p); |
| 337 | + if (error) |
| 338 | + goto reset_fcntl; |
| 339 | + } |
| 340 | + if (i & FASYNC) { |
| 341 | + int fl = tmp & FASYNC; |
| 342 | + error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, &fl, p); |
| 343 | + if (error) { |
| 344 | + if (i & FNONBLOCK) { |
| 345 | + tmp = fp->f_flag & FNONBLOCK; |
| 346 | + (void)(*fp->f_ops->fo_ioctl)(fp, |
| 347 | + FIONBIO, &tmp, p); |
| 348 | + } |
| 349 | + goto reset_fcntl; |
| 350 | + } |
| 351 | + } |
| 352 | + fp->f_flag = (fp->f_flag & ~FCNTLFLAGS) | tmp; |
| 353 | + break; |
| 354 | + reset_fcntl: |
| 355 | + (void)(*fp->f_ops->fo_fcntl)(fp, F_SETFL, &fp->f_flag, p); |
346 | 356 | break; |
347 | 357 |
|
348 | 358 | case F_GETOWN: |
|
0 commit comments