[PATCH] kpty weirdness (was: Re: kdelibs/kdecore)
Oswald Buddenhagen
ossi at kde.org
Thu Jan 15 21:01:41 GMT 2004
On Thu, Jan 15, 2004 at 09:24:16PM +0100, Waldo Bastian wrote:
> > /me looks at waldo, the supposed (co-)maintainer of that stuff. :)
> >
>
> Can you repost the patch?
>
sure ... *grmpf* ;)
once with -w (for reading the changes) and once without -w (for reading
the patched source). :)
greetings
--
Hi! I'm a .signature virus! Copy me into your ~/.signature, please!
--
Chaos, panic, and disorder - my work here is done.
-------------- next part --------------
Index: kpty.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kpty.cpp,v
retrieving revision 1.18
diff -U2 -w -r1.18 kpty.cpp
--- kpty.cpp 13 Jan 2004 01:02:29 -0000 1.18
+++ kpty.cpp 15 Jan 2004 20:58:28 -0000
@@ -159,5 +159,5 @@
struct KPtyPrivate {
KPtyPrivate() :
- xonXoff(false), needGrantPty(false),
+ xonXoff(false),
masterFd(-1), slaveFd(-1)
{
@@ -168,5 +168,4 @@
bool xonXoff : 1;
- bool needGrantPty : 1;
int masterFd;
int slaveFd;
@@ -204,13 +203,6 @@
// We try, as we know them, one by one.
-#if defined(HAVE_OPENPTY)
- if (openpty(&d->masterFd, &d->slaveFd, NULL, NULL, NULL) == 0)
- {
- d->ttyName = ttyname(d->slaveFd);
- goto gotpty2;
- }
-#endif
-#if defined(HAVE_PTSNAME)
+#if defined(HAVE_PTSNAME) && defined(HAVE_GRANTPT)
#ifdef _AIX
d->masterFd = ::open("/dev/ptc",O_RDWR);
@@ -222,6 +214,7 @@
char *ptsn = ptsname(d->masterFd);
if (ptsn) {
+ grantpt(d->masterFd);
d->ttyName = ptsn;
- goto gotpty1;
+ goto gotpty;
} else {
::close(d->masterFd);
@@ -254,6 +247,18 @@
}
#endif /* sun */
- if (geteuid() == 0 || access(d->ttyName.data(),R_OK|W_OK) == 0)
- goto gotpty1; // Success !!
+ if (!access(d->ttyName.data(),R_OK|W_OK)) // checks availability based on permission bits
+ {
+ if (!geteuid())
+ {
+ struct group* p = getgrnam(TTY_GROUP);
+ if (!p)
+ p = getgrnam("wheel");
+ gid_t gid = p ? p->gr_gid : getgid ();
+
+ chown(d->ttyName.data(), getuid(), gid);
+ chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP);
+ }
+ goto gotpty;
+ }
::close(d->masterFd);
d->masterFd = -1;
@@ -265,28 +270,11 @@
return false;
- gotpty1:
-#if defined(HAVE_GRANTPT)
- grantpt(d->masterFd);
-#else
- {
- /* Get the group ID of the special `tty' group. */
- struct group* p = getgrnam(TTY_GROUP); /* posix */
- gid_t gid = p ? p->gr_gid : getgid (); /* posix */
-
- chown(d->ttyName.data(), getuid(), gid);
- chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP);
- }
-#endif
- gotpty2:
+ gotpty:
struct stat st;
if (stat(d->ttyName.data(), &st))
return false; // this just cannot happen ... *cough*
- d->needGrantPty = st.st_uid != getuid() || (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH));
-
-#ifdef BSD
- revoke(d->ttyName.data());
-#endif
-
- if (!chownpty(true))
+ if (((st.st_uid != getuid()) ||
+ (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH))) &&
+ !chownpty(true))
{
kdWarning(175)
@@ -295,10 +283,13 @@
}
+#ifdef BSD
+ revoke(d->ttyName.data());
+#endif
+
#ifdef HAVE_UNLOCKPT
unlockpt(d->masterFd);
#endif
- if (d->slaveFd < 0) { // slave pty not yet opened?
- d->slaveFd = ::open(d->ttyName, O_RDWR);
+ d->slaveFd = ::open(d->ttyName.data(), O_RDWR);
if (d->slaveFd < 0)
{
@@ -308,5 +299,4 @@
return false;
}
- }
#if (defined(__svr4__) || defined(__sgi__))
@@ -348,7 +338,17 @@
if (d->masterFd < 0)
return;
- chown(d->ttyName.data(), 0, 0);
+ // don't bother resetting unix98 pty, it will go away after closing master anyway.
+ if (memcmp(d->ttyName.data(), "/dev/pts/", 9)) {
+ if (!geteuid()) {
+ struct stat st;
+ if (!stat(d->ttyName.data(), &st)) {
+ chown(d->ttyName.data(), 0, st.st_gid == getgid() ? 0 : -1);
chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+ }
+ } else {
+ fcntl(d->masterFd, F_SETFD, 0);
chownpty(false);
+ }
+ }
::close(d->slaveFd);
::close(d->masterFd);
@@ -492,8 +492,4 @@
bool KPty::chownpty(bool grant)
{
- if (!d->needGrantPty)
- return true;
-
- fcntl(d->masterFd, F_SETFD, 0);
KProcess proc;
proc << locate("exe", BASE_CHOWN) << (grant?"--grant":"--revoke") << QString::number(d->masterFd);
Index: kgrantpty.c
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kgrantpty.c,v
retrieving revision 1.13
diff -U2 -w -r1.13 kgrantpty.c
--- kgrantpty.c 20 Nov 2003 15:53:10 -0000 1.13
+++ kgrantpty.c 15 Jan 2004 20:58:28 -0000
@@ -25,6 +25,7 @@
*/
+#include <config.h>
+
#include <sys/types.h>
-#include <sys/param.h> /* for BSD */
#include <errno.h>
#include <grp.h>
@@ -46,5 +47,4 @@
int main (int argc, char *argv[])
{
- char* pty;
struct stat st;
struct group* p;
@@ -72,27 +72,16 @@
}
- /* setup parameters for the operation ***********************************/
-
- if (!strcmp(argv[1],"--grant"))
- {
- uid = getuid(); /* current user id */
- mod = S_IRUSR | S_IWUSR | S_IWGRP;
- }
- else
- {
- uid = 0; /* root */
- mod = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
- }
- /* Get the group ID of the special `tty' group. */
- p = getgrnam(TTY_GROUP); /* posix */
- gid = p ? p->gr_gid : getgid (); /* posix */
fd = atoi(argv[2]);
- /* get slave pty name from master pty file handle in PTY_FILENO *********/
-
+ /* get slave pty name from master pty file handle *********/
+#ifdef HAVE_PTSNAME
+ tty = ptsname(fd);
+ if (!tty)
+#endif
+ {
/* Check that fd is a valid master pseudo terminal. */
- pty = ttyname(fd); /* posix */
+ char *pty = ttyname(fd);
-#if defined(BSD_PTY_HACK)
+#ifdef BSD_PTY_HACK
if (pty == NULL)
{
@@ -111,9 +100,4 @@
struct stat dsb;
- if (uid == 0) {
- p = getgrnam("wheel");
- gid = p ? p->gr_gid : getgid();
- }
-
if (fstat(fd, &dsb) != -1) {
if ((dp = opendir(_PATH_DEV)) != NULL) {
@@ -140,8 +124,7 @@
return 1; /* FAIL */
}
- close(fd);
/* matches /dev/pty?? */
- if (strlen(pty) < 8 || strncmp(pty,"/dev/pty",8))
+ if (memcmp(pty,"/dev/pty",8))
{
fprintf(stderr,"%s: determined a strange pty name `%s'.\n",argv[0],pty);
@@ -152,4 +135,5 @@
strcpy(tty,"/dev/tty");
strcat(tty,pty+8);
+ }
/* Check that the returned slave pseudo terminal is a character device. */
@@ -160,4 +144,22 @@
}
+ /* setup parameters for the operation ***********************************/
+
+ if (!strcmp(argv[1],"--grant"))
+ {
+ uid = getuid();
+ p = getgrnam(TTY_GROUP);
+ if (!p)
+ p = getgrnam("wheel");
+ gid = p ? p->gr_gid : getgid ();
+ mod = S_IRUSR | S_IWUSR | S_IWGRP;
+ }
+ else
+ {
+ uid = 0;
+ gid = st.st_gid == getgid () ? 0 : -1;
+ mod = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+ }
+
/* Perform the actual chown/chmod ************************************/
@@ -174,12 +176,4 @@
}
-#ifdef BSD
- if (revoke(tty) < 0)
- {
- fprintf(stderr,"%s: cannot revoke %s: %s\n",argv[0],tty,strerror(errno));
- return 1; /* FAIL */
- }
-#endif
-
return 0; /* OK */
}
-------------- next part --------------
Index: kpty.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kpty.cpp,v
retrieving revision 1.18
diff -U2 -r1.18 kpty.cpp
--- kpty.cpp 13 Jan 2004 01:02:29 -0000 1.18
+++ kpty.cpp 15 Jan 2004 20:59:49 -0000
@@ -159,5 +159,5 @@
struct KPtyPrivate {
KPtyPrivate() :
- xonXoff(false), needGrantPty(false),
+ xonXoff(false),
masterFd(-1), slaveFd(-1)
{
@@ -168,5 +168,4 @@
bool xonXoff : 1;
- bool needGrantPty : 1;
int masterFd;
int slaveFd;
@@ -204,13 +203,6 @@
// We try, as we know them, one by one.
-#if defined(HAVE_OPENPTY)
- if (openpty(&d->masterFd, &d->slaveFd, NULL, NULL, NULL) == 0)
- {
- d->ttyName = ttyname(d->slaveFd);
- goto gotpty2;
- }
-#endif
-#if defined(HAVE_PTSNAME)
+#if defined(HAVE_PTSNAME) && defined(HAVE_GRANTPT)
#ifdef _AIX
d->masterFd = ::open("/dev/ptc",O_RDWR);
@@ -222,6 +214,7 @@
char *ptsn = ptsname(d->masterFd);
if (ptsn) {
+ grantpt(d->masterFd);
d->ttyName = ptsn;
- goto gotpty1;
+ goto gotpty;
} else {
::close(d->masterFd);
@@ -254,6 +247,18 @@
}
#endif /* sun */
- if (geteuid() == 0 || access(d->ttyName.data(),R_OK|W_OK) == 0)
- goto gotpty1; // Success !!
+ if (!access(d->ttyName.data(),R_OK|W_OK)) // checks availability based on permission bits
+ {
+ if (!geteuid())
+ {
+ struct group* p = getgrnam(TTY_GROUP);
+ if (!p)
+ p = getgrnam("wheel");
+ gid_t gid = p ? p->gr_gid : getgid ();
+
+ chown(d->ttyName.data(), getuid(), gid);
+ chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP);
+ }
+ goto gotpty;
+ }
::close(d->masterFd);
d->masterFd = -1;
@@ -265,28 +270,11 @@
return false;
- gotpty1:
-#if defined(HAVE_GRANTPT)
- grantpt(d->masterFd);
-#else
- {
- /* Get the group ID of the special `tty' group. */
- struct group* p = getgrnam(TTY_GROUP); /* posix */
- gid_t gid = p ? p->gr_gid : getgid (); /* posix */
-
- chown(d->ttyName.data(), getuid(), gid);
- chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP);
- }
-#endif
- gotpty2:
+ gotpty:
struct stat st;
if (stat(d->ttyName.data(), &st))
return false; // this just cannot happen ... *cough*
- d->needGrantPty = st.st_uid != getuid() || (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH));
-
-#ifdef BSD
- revoke(d->ttyName.data());
-#endif
-
- if (!chownpty(true))
+ if (((st.st_uid != getuid()) ||
+ (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH))) &&
+ !chownpty(true))
{
kdWarning(175)
@@ -295,17 +283,19 @@
}
+#ifdef BSD
+ revoke(d->ttyName.data());
+#endif
+
#ifdef HAVE_UNLOCKPT
unlockpt(d->masterFd);
#endif
- if (d->slaveFd < 0) { // slave pty not yet opened?
- d->slaveFd = ::open(d->ttyName, O_RDWR);
- if (d->slaveFd < 0)
- {
- kdWarning(175) << "Can't open slave pseudo teletype" << endl;
- ::close(d->masterFd);
- d->masterFd = -1;
- return false;
- }
+ d->slaveFd = ::open(d->ttyName.data(), O_RDWR);
+ if (d->slaveFd < 0)
+ {
+ kdWarning(175) << "Can't open slave pseudo teletype" << endl;
+ ::close(d->masterFd);
+ d->masterFd = -1;
+ return false;
}
@@ -348,7 +338,17 @@
if (d->masterFd < 0)
return;
- chown(d->ttyName.data(), 0, 0);
- chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
- chownpty(false);
+ // don't bother resetting unix98 pty, it will go away after closing master anyway.
+ if (memcmp(d->ttyName.data(), "/dev/pts/", 9)) {
+ if (!geteuid()) {
+ struct stat st;
+ if (!stat(d->ttyName.data(), &st)) {
+ chown(d->ttyName.data(), 0, st.st_gid == getgid() ? 0 : -1);
+ chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+ }
+ } else {
+ fcntl(d->masterFd, F_SETFD, 0);
+ chownpty(false);
+ }
+ }
::close(d->slaveFd);
::close(d->masterFd);
@@ -492,8 +492,4 @@
bool KPty::chownpty(bool grant)
{
- if (!d->needGrantPty)
- return true;
-
- fcntl(d->masterFd, F_SETFD, 0);
KProcess proc;
proc << locate("exe", BASE_CHOWN) << (grant?"--grant":"--revoke") << QString::number(d->masterFd);
Index: kgrantpty.c
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kgrantpty.c,v
retrieving revision 1.13
diff -U2 -r1.13 kgrantpty.c
--- kgrantpty.c 20 Nov 2003 15:53:10 -0000 1.13
+++ kgrantpty.c 15 Jan 2004 20:59:49 -0000
@@ -25,6 +25,7 @@
*/
+#include <config.h>
+
#include <sys/types.h>
-#include <sys/param.h> /* for BSD */
#include <errno.h>
#include <grp.h>
@@ -46,5 +47,4 @@
int main (int argc, char *argv[])
{
- char* pty;
struct stat st;
struct group* p;
@@ -72,84 +72,68 @@
}
- /* setup parameters for the operation ***********************************/
-
- if (!strcmp(argv[1],"--grant"))
- {
- uid = getuid(); /* current user id */
- mod = S_IRUSR | S_IWUSR | S_IWGRP;
- }
- else
- {
- uid = 0; /* root */
- mod = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
- }
- /* Get the group ID of the special `tty' group. */
- p = getgrnam(TTY_GROUP); /* posix */
- gid = p ? p->gr_gid : getgid (); /* posix */
fd = atoi(argv[2]);
- /* get slave pty name from master pty file handle in PTY_FILENO *********/
-
- /* Check that fd is a valid master pseudo terminal. */
- pty = ttyname(fd); /* posix */
-
-#if defined(BSD_PTY_HACK)
- if (pty == NULL)
+ /* get slave pty name from master pty file handle *********/
+#ifdef HAVE_PTSNAME
+ tty = ptsname(fd);
+ if (!tty)
+#endif
{
- /*
- Hack to make kgrantpty work on some versions of FreeBSD (and possibly
- other systems): ttyname(3) does not work with a file descriptor opened
- on a /dev/pty?? device.
-
- Instead, this code looks through all the devices in /dev for a device
- which has the same inode as our PTY_FILENO descriptor... if found, we
- have the name for our pty.
- */
-
- struct dirent *dirp;
- DIR *dp;
- struct stat dsb;
-
- if (uid == 0) {
- p = getgrnam("wheel");
- gid = p ? p->gr_gid : getgid();
- }
+ /* Check that fd is a valid master pseudo terminal. */
+ char *pty = ttyname(fd);
- if (fstat(fd, &dsb) != -1) {
- if ((dp = opendir(_PATH_DEV)) != NULL) {
- while ((dirp = readdir(dp))) {
- if (dirp->d_fileno != dsb.st_ino)
- continue;
- pty = malloc(sizeof(_PATH_DEV) + strlen(dirp->d_name));
- if (pty) {
- strcpy(pty, _PATH_DEV);
- strcat(pty, dirp->d_name);
+#ifdef BSD_PTY_HACK
+ if (pty == NULL)
+ {
+ /*
+ Hack to make kgrantpty work on some versions of FreeBSD (and possibly
+ other systems): ttyname(3) does not work with a file descriptor opened
+ on a /dev/pty?? device.
+
+ Instead, this code looks through all the devices in /dev for a device
+ which has the same inode as our PTY_FILENO descriptor... if found, we
+ have the name for our pty.
+ */
+
+ struct dirent *dirp;
+ DIR *dp;
+ struct stat dsb;
+
+ if (fstat(fd, &dsb) != -1) {
+ if ((dp = opendir(_PATH_DEV)) != NULL) {
+ while ((dirp = readdir(dp))) {
+ if (dirp->d_fileno != dsb.st_ino)
+ continue;
+ pty = malloc(sizeof(_PATH_DEV) + strlen(dirp->d_name));
+ if (pty) {
+ strcpy(pty, _PATH_DEV);
+ strcat(pty, dirp->d_name);
+ }
+ break;
}
- break;
- }
- (void) closedir(dp);
+ (void) closedir(dp);
+ }
}
}
- }
#endif
- if (pty == NULL)
- {
- fprintf(stderr,"%s: cannot determine pty name.\n",argv[0]);
- return 1; /* FAIL */
- }
- close(fd);
+ if (pty == NULL)
+ {
+ fprintf(stderr,"%s: cannot determine pty name.\n",argv[0]);
+ return 1; /* FAIL */
+ }
- /* matches /dev/pty?? */
- if (strlen(pty) < 8 || strncmp(pty,"/dev/pty",8))
- {
- fprintf(stderr,"%s: determined a strange pty name `%s'.\n",argv[0],pty);
- return 1; /* FAIL */
- }
+ /* matches /dev/pty?? */
+ if (memcmp(pty,"/dev/pty",8))
+ {
+ fprintf(stderr,"%s: determined a strange pty name `%s'.\n",argv[0],pty);
+ return 1; /* FAIL */
+ }
- tty = malloc(strlen(pty) + 1);
- strcpy(tty,"/dev/tty");
- strcat(tty,pty+8);
+ tty = malloc(strlen(pty) + 1);
+ strcpy(tty,"/dev/tty");
+ strcat(tty,pty+8);
+ }
/* Check that the returned slave pseudo terminal is a character device. */
@@ -160,4 +144,22 @@
}
+ /* setup parameters for the operation ***********************************/
+
+ if (!strcmp(argv[1],"--grant"))
+ {
+ uid = getuid();
+ p = getgrnam(TTY_GROUP);
+ if (!p)
+ p = getgrnam("wheel");
+ gid = p ? p->gr_gid : getgid ();
+ mod = S_IRUSR | S_IWUSR | S_IWGRP;
+ }
+ else
+ {
+ uid = 0;
+ gid = st.st_gid == getgid () ? 0 : -1;
+ mod = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+ }
+
/* Perform the actual chown/chmod ************************************/
@@ -174,12 +176,4 @@
}
-#ifdef BSD
- if (revoke(tty) < 0)
- {
- fprintf(stderr,"%s: cannot revoke %s: %s\n",argv[0],tty,strerror(errno));
- return 1; /* FAIL */
- }
-#endif
-
return 0; /* OK */
}
More information about the kde-core-devel
mailing list