Page MenuHomeFreeBSD

D60701.id189728.diff
No OneTemporary

D60701.id189728.diff

diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -59,6 +59,7 @@
#include <sys/stat.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
+#include <sys/sysent.h>
#include <sys/time.h>
#include <sys/ttycom.h>
#include <sys/unistd.h>
@@ -699,7 +700,7 @@
struct cdev *dev = vp->v_rdev;
struct cdevsw *dsw;
struct devfs_dirent *de = vp->v_data;
- int dflags, error, ref, vp_locked;
+ int dflags, error, hold_ctty, ref, usecount, vp_locked;
/*
* XXX: Don't call d_close() if we were called because of
@@ -716,7 +717,13 @@
* process' controlling terminal. In that case,
* if the reference count is 2 (this last descriptor
* plus the session), release the reference from the session.
+ *
+ * Linux keeps the controlling terminal after the last
+ * slave descriptor is closed. A Linux closer leaves the
+ * session reference in place; FLASTCLOSE is still forced
+ * below so the driver sees the last user close.
*/
+ hold_ctty = 0;
if (de->de_usecount == 2 && td != NULL) {
p = td->td_proc;
PROC_LOCK(p);
@@ -729,9 +736,13 @@
mtx_lock(&devfs_de_interlock);
VI_LOCK(vp);
if (devfs_usecountl(vp) == 2 && !VN_IS_DOOMED(vp)) {
- p->p_session->s_ttyvp = NULL;
- p->p_session->s_ttydp = NULL;
- oldvp = vp;
+ if (SV_PROC_ABI(p) == SV_ABI_LINUX)
+ hold_ctty = 1;
+ else {
+ p->p_session->s_ttyvp = NULL;
+ p->p_session->s_ttydp = NULL;
+ oldvp = vp;
+ }
}
VI_UNLOCK(vp);
mtx_unlock(&devfs_de_interlock);
@@ -756,12 +767,23 @@
if (dsw == NULL)
return (ENXIO);
dflags = 0;
+ if (hold_ctty != 0) {
+ sx_slock(&proctree_lock);
+ SESS_LOCK(p->p_session);
+ }
mtx_lock(&devfs_de_interlock);
VI_LOCK(vp);
- if (devfs_usecountl(vp) == 1)
+ usecount = devfs_usecountl(vp);
+ if (usecount == 1 ||
+ (hold_ctty != 0 && usecount == 2 && !VN_IS_DOOMED(vp) &&
+ p->p_session->s_ttyvp == vp))
dflags |= FLASTCLOSE;
devfs_usecount_subl(vp);
mtx_unlock(&devfs_de_interlock);
+ if (hold_ctty != 0) {
+ SESS_UNLOCK(p->p_session);
+ sx_sunlock(&proctree_lock);
+ }
if (VN_IS_DOOMED(vp)) {
/* Forced close. */
dflags |= FREVOKE | FNONBLOCK;

File Metadata

Mime Type
text/plain
Expires
Thu, Oct 15, 11:47 PM (4 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40805275
Default Alt Text
D60701.id189728.diff (2 KB)

Event Timeline