Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 Nov 2000 08:10:16 -0800
From:      Keith Walker <kew@icehouse.net>
To:        Cyrille Lefevre <clefevre@citeweb.net>
Cc:        <ports@FreeBSD.ORG>
Subject:   Re: KDE 2.0 Problems
Message-ID:  <00112908101600.02164@mars.walker.dom>
In-Reply-To: <aeaj1j04.fsf@gits.dyndns.org>
References:  <0aed01c0589c$224d07f0$9828f99f@shl.com> <aeaj1j04.fsf@gits.dyndns.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--------------Boundary-00=_4LNS43A89ZYHIEMY35RP
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: 8bit

On Tuesday 28 November 2000 20:48, Cyrille Lefevre wrote:
> "Tim Pushor" <timp@crossthread.com> writes:
> > I am having some trouble with KDE 2.0 and FreeBSD 4.x. (currently 4.2). I
> > have both compiled KDE from source, and installed the packages found in
> > packages-current on freebsd.org.
>
> me too.

Ok, here's some *very* unofficial patches that seem to make everything 
better. Problem is, I'm new at this whole "ports" game as well as not all 
that good at C/C++ programming. 

The problems appear to be in the way that FreeBSD handles pty's, a call to 
ttyname (which always fails with ptys) and the way that the konsole_grantpty 
program is called. The fix for the calling of konsole_grantpty is probably 
big-time overkill, but it works.

In order to have these patches work, you'll have to start fresh (make clean 
in the kdebase-2.0 port), then copy the two attached patch files into 
.../kdebase-2.0/files, then do a make.

As the one patch file overwrites the original patch, make sure that you make 
a backup of that file (.../files/patch-TEPty.C) so that you can restore 
everything in case this doesn't work for you. Don't make the backup in the 
"files" directory or the patch step of the make will fail.

Everything *should* work; it works for me but ymmv of course.

-- 
Keith Walker
kew@icehouse.net
--------------Boundary-00=_4LNS43A89ZYHIEMY35RP
Content-Type: text/english;
  name="patch-TEPty.C"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="patch-TEPty.C"

--- konsole/src/TEPty.C.orig	Tue Oct  3 12:57:30 2000
+++ konsole/src/TEPty.C	Wed Nov 29 07:24:50 2000
@@ -180,27 +180,71 @@
 // param grant: 1 to grant, 0 to revoke
 // returns 1 on success 0 on fail
 {
-  pid_t pid = fork();
-  if (pid < 0)
-  {
-    return 0;
-  }
-  if (pid == 0)
-  {
-    /* We pass the master pseudo terminal as file descriptor PTY_FILENO. */
-    if (fd != PTY_FILENO && dup2(fd, PTY_FILENO) < 0) exit(1);
-    QString path = locate("exe", BASE_CHOWN);
+	// -----------------------------------------------------------------------
+	// Ok, I lifted this from the FreeBSD source for the system(3) call
+	// which ought to solve the problem of the call not working correctly.
+	// The problem with the old way of doing it? I quote...
+	//
+	// From Advanced Programming in the Unix Environment:
+	// "The problem [...] is that we have no guarantee after the fork whether
+	// the parent or child runs first."
+	//
+	// We were trying to wait on a non-existant child, causing a ECHILD
+	// error, which would make the code fail. We take the steps necessary
+	// to handle signals correctly which ensures a proper call to the
+	// external program. (kew)
+	// -----------------------------------------------------------------------
+  pid_t pid;
+  int pstat;
+  struct sigaction ign;
+  struct sigaction intact;	// interupt action
+  struct sigaction quitact;	// quit action
+  sigset_t newsigblock, oldsigblock;
+	QString path;
+
+  ign.sa_handler = SIG_IGN;
+  sigemptyset(&ign.sa_mask);
+  ign.sa_flags = 0;
+  sigaction(SIGINT, &ign, &intact);
+  sigaction(SIGQUIT, &ign, &quitact);
+  sigemptyset(&newsigblock);
+  sigaddset(&newsigblock, SIGCHLD);
+  sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock);
+
+  switch (pid = fork()) {
+  case -1:
+    return(0);
+		break;
+  case 0:			// child
+    if (fd != PTY_FILENO && dup2(fd, PTY_FILENO) < 0)
+      exit(1);
+    path = locate("exe", BASE_CHOWN);
+
+    sigaction(SIGINT, &intact, NULL);
+    sigaction(SIGQUIT, &quitact, NULL);
+    sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
     execle(path.ascii(), BASE_CHOWN, grant?"--grant":"--revoke", NULL, NULL);
-    exit(1); // should not be reached
-  }
-  if (pid > 0)
-  { int w;
-  retry:
-    int rc = waitpid (pid, &w, 0);
-    if ((rc == -1) && (errno == EINTR))
-      goto retry;
-    return (rc != -1 && WIFEXITED(w) && WEXITSTATUS(w) == 0);
+    exit(1);
+		break;
+  default:
+    do {
+      pid = waitpid(pid, &pstat, 0);
+    } while (pid == -1 && errno == EINTR);
+    break;
   }
+  sigaction(SIGINT, &intact, NULL);
+  sigaction(SIGQUIT, &quitact, NULL);
+  sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
+
+  if (pid == -1) {
+    return 0;
+	}
+  else if (WIFEXITED(pstat) && (WEXITSTATUS(pstat) == 0)) {
+    return 1;
+	}
+  else {
+    return 0;
+	}
   return 0; //dummy.
 }
 
@@ -225,7 +269,7 @@
 #ifdef HAVE_UTEMPTER
   removeLineFromUtmp(ttynam, fd);
 #elif defined(USE_LOGIN)
-  char *tty_name=ttyname(0);
+  char *tty_name=ttyname(fd);
   if (tty_name)
         logout(tty_name);
 #endif

--------------Boundary-00=_4LNS43A89ZYHIEMY35RP
Content-Type: text/x-c;
  name="patch-konsole_grantpty.c"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="patch-konsole_grantpty.c"

--- konsole/src/konsole_grantpty.c.orig	Wed Nov 29 07:31:10 2000
+++ konsole/src/konsole_grantpty.c	Wed Nov 29 07:24:57 2000
@@ -31,13 +31,15 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <dirent.h>
+#include <paths.h>
 
 #define PTY_FILENO 3    /* keep in sync with grantpty */
 #define TTY_GROUP "tty"
 
 int main (int argc, char *argv[])
 {
-  char*         pty;
+  char*         pty = NULL;
   struct stat   st;
   struct group* p;
   gid_t         gid;
@@ -81,6 +83,7 @@
 
   /* get slave pty name from master pty file handle in PTY_FILENO *********/
 
+#if 0
   /* Check that PTY_FILENO is a valid master pseudo terminal.  */
   pty = ttyname(PTY_FILENO);          /* posix */
   if (pty == NULL)
@@ -89,6 +92,42 @@
     return 1; /* FAIL */
   }
   close(PTY_FILENO);
+#else
+	/* The trouble with the ifdef'd-out portion above is that ttyname()
+	** does not work correctly when not passed a valid tty, but a pseudotty
+	** instead. All we're doing here is finding out what the name of
+	** the associated pty is without having to pass it in on the command line.
+	** Nothing complex.
+	*/
+	{
+		struct stat sb;
+		struct stat dsb;
+		struct dirent *dirp;
+		static char buf[sizeof(_PATH_DEV) + MAXNAMLEN] = _PATH_DEV;
+		DIR *dp;
+		
+		pty = NULL;
+		
+		if (fstat(PTY_FILENO, &sb))
+			return 1; /* FAIL */
+		if ((dp = opendir(_PATH_DEV)) == NULL)
+			return 1; /* FAIL */
+		
+		while ((dirp = readdir(dp))) {
+			if (dirp->d_fileno != sb.st_ino)
+				continue;
+			bcopy(dirp->d_name, buf + sizeof(_PATH_DEV) - 1, dirp->d_namlen+1);
+			/*fprintf(stderr, "looking at %s\n", buf);*/
+			if (stat(buf, &dsb) || sb.st_dev != dsb.st_dev || sb.st_ino != dsb.st_ino)
+				continue;
+			pty = buf;
+		}
+		closedir(dp);
+		if (pty == NULL)
+			return 1; /* FAIL */
+	}
+	/*fprintf(stderr, "successful at finding %s\n", pty);*/
+#endif
 
   /* matches /dev/pty?? */
   if (strlen(pty) < 8 || strncmp(pty,"/dev/pty",8))
@@ -120,6 +159,8 @@
     fprintf(stderr,"%s: cannot chmod %s.\n",argv[0],tty); perror("Reason");
     return 1; /* FAIL */
   }
+	
+	/*fprintf(stderr, "made it here\n");*/
 
   return 0; /* OK */
 }

--------------Boundary-00=_4LNS43A89ZYHIEMY35RP--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ports" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?00112908101600.02164>