Unix Programming - sync problems over fork/child using openpty()

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > February 2007 > sync problems over fork/child using openpty()





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author sync problems over fork/child using openpty()
K-mart Cashier

2007-02-05, 1:18 pm

Sometimes the following program will print 2 lines, sometimes 3 lines,
and sometimes one. Can someone tell me the error in my logic?

#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/time.h>

#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <tzfile.h>
#include <unistd.h>
#include <event.h>

#include <util.h>
#include <err.h>

int master, slave;
struct termios tt;

#define COUNT 5

int main(int argc, char *argv[])
{
int pid;
int i;

/*char channel[] = " \"#party\"\0";*/
char c[] = "test\n";

struct winsize win;
struct timeval tv;

fd_set rfds;
int status=0;


(void) tcgetattr(STDIN_FILENO, &tt);
(void) ioctl(STDIN_FILENO, TIOCGWINSZ, &win);

if (openpty(&master, &slave, NULL, &tt, &win) == -1)
perror("openpty");

if ((pid = fork()) < 0) {
return(-1);
} else if (pid == 0) { /* child */

if (setsid() < 0)
perror("setsid error");


(void)close(master);

if (ioctl(slave, TIOCSCTTY, (char *)0) < 0)
perror("TIOCSCTTY error");

if (tcsetattr(slave, TCSANOW, &tt) < 0)
perror("tcsetattr error on slave pty");

if (ioctl(slave, TIOCSWINSZ, &tt) < 0)
perror("TIOCSWINSZ error on slave pty");


if (dup2(slave, 0) != STDIN_FILENO)
perror("dup2 error to stdin");
if (dup2(slave, 1) != STDOUT_FILENO)
perror("dup2 error to stdout");
if (dup2(slave, 2) != STDERR_FILENO)
perror("dup2 error to stderr");
if (execlp("party","party",(char *)0) < 0)
perror("can't execute");


struct termios stermios;

if (tcgetattr(slave, &stermios) < 0)
perror("tcgetattr error");

stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);

stermios.c_oflag &= ~(ONLCR);

if (tcsetattr(slave, TCSANOW, &stermios) < 0)
perror("tcsetattr error");


tv.tv_sec = 0;
tv.tv_usec = 5000;
FD_ZERO(&rfds);
FD_SET(master, &rfds);

/*while (select(master+1, &rfds, 0, 0, &tv)>0 && read(master,
&channel, 1)>0) {
tv.tv_sec = 1;
tv.tv_usec = 0;

FD_ZERO(&rfds);
FD_SET(master, &rfds);
}*/


return(0);
}/*end child */

else{
for(i=0; i < COUNT; i++) {
sleep(3);
write(master, &c, strlen(c));
}
} /*parent*/



/*wait(&status);
if (status != 0) {
fprintf(stderr, "unable to write.\n");
exit(EXIT_FAILURE);
}*/

}


Thanks,
Chad

K-mart Cashier

2007-02-06, 1:33 am


K-mart Cashier wrote:
> Sometimes the following program will print 2 lines, sometimes 3 lines,
> and sometimes one. Can someone tell me the error in my logic?
>
> #include <sys/types.h>
> #include <sys/wait.h>
> #include <sys/stat.h>
> #include <sys/ioctl.h>
> #include <sys/time.h>
>
> #include <errno.h>
> #include <fcntl.h>
> #include <paths.h>
> #include <signal.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <termios.h>
> #include <tzfile.h>
> #include <unistd.h>
> #include <event.h>
>
> #include <util.h>
> #include <err.h>
>
> int master, slave;
> struct termios tt;
>
> #define COUNT 5
>
> int main(int argc, char *argv[])
> {
> int pid;
> int i;
>
> /*char channel[] = " \"#party\"\0";*/
> char c[] = "test\n";
>
> struct winsize win;
> struct timeval tv;
>
> fd_set rfds;
> int status=0;
>
>
> (void) tcgetattr(STDIN_FILENO, &tt);
> (void) ioctl(STDIN_FILENO, TIOCGWINSZ, &win);
>
> if (openpty(&master, &slave, NULL, &tt, &win) == -1)
> perror("openpty");
>
> if ((pid = fork()) < 0) {
> return(-1);
> } else if (pid == 0) { /* child */
>
> if (setsid() < 0)
> perror("setsid error");
>
>
> (void)close(master);
>
> if (ioctl(slave, TIOCSCTTY, (char *)0) < 0)
> perror("TIOCSCTTY error");
>
> if (tcsetattr(slave, TCSANOW, &tt) < 0)
> perror("tcsetattr error on slave pty");
>
> if (ioctl(slave, TIOCSWINSZ, &tt) < 0)
> perror("TIOCSWINSZ error on slave pty");
>
>
> if (dup2(slave, 0) != STDIN_FILENO)
> perror("dup2 error to stdin");
> if (dup2(slave, 1) != STDOUT_FILENO)
> perror("dup2 error to stdout");
> if (dup2(slave, 2) != STDERR_FILENO)
> perror("dup2 error to stderr");
> if (execlp("party","party",(char *)0) < 0)
> perror("can't execute");
>
>
> struct termios stermios;
>
> if (tcgetattr(slave, &stermios) < 0)
> perror("tcgetattr error");
>
> stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
>
> stermios.c_oflag &= ~(ONLCR);
>
> if (tcsetattr(slave, TCSANOW, &stermios) < 0)
> perror("tcsetattr error");
>
>
> tv.tv_sec = 0;
> tv.tv_usec = 5000;
> FD_ZERO(&rfds);
> FD_SET(master, &rfds);
>
> /*while (select(master+1, &rfds, 0, 0, &tv)>0 && read(master,
> &channel, 1)>0) {
> tv.tv_sec = 1;
> tv.tv_usec = 0;
>
> FD_ZERO(&rfds);
> FD_SET(master, &rfds);
> }*/
>
>
> return(0);
> }/*end child */
>
> else{
> for(i=0; i < COUNT; i++) {
> sleep(3);
> write(master, &c, strlen(c));
> }
> } /*parent*/
>
>
>
> /*wait(&status);
> if (status != 0) {
> fprintf(stderr, "unable to write.\n");
> exit(EXIT_FAILURE);
> }*/
>
> }
>
>
> Thanks,
> Chad


Okay, using the gnu debugger, I noticed that will sometimes
intermingle the output. If I insert
close(master);
close(slave);

after
write(master, &c, strlen(c));

I don't get junk in the output.

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com