Skip to content

Commit b2f39a1

Browse files
author
dsl
committed
Correct rewinding if FIONBIO or FIOASYNC fail in F_SETFL
(code use to always turn off FIONBIO if FIOASYNC fails) (approved by christos)
1 parent 5d23c3b commit b2f39a1

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

sys/kern/kern_descrip.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
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 $ */
22

33
/*
44
* Copyright (c) 1982, 1986, 1989, 1991, 1993
@@ -41,7 +41,7 @@
4141
*/
4242

4343
#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 $");
4545

4646
#include <sys/param.h>
4747
#include <sys/systm.h>
@@ -329,20 +329,30 @@ sys_fcntl(struct lwp *l, void *v, register_t *retval)
329329
tmp = FFLAGS((long)SCARG(uap, arg)) & FCNTLFLAGS;
330330
error = (*fp->f_ops->fo_fcntl)(fp, F_SETFL, &tmp, p);
331331
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);
346356
break;
347357

348358
case F_GETOWN:

0 commit comments

Comments
 (0)