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>