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, 7:05 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, 4:08 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.
|
|
|
|
|