Example #1
0
    bool start()
    {
        fdMaster = getpt();
        if (fdMaster < 0) {
            LOGE("Error %d on getpt()", errno);
            return false;
        }

        if (unlockpt(fdMaster) != 0) {
            LOGE("Error %d on unlockpt()", errno);
            return false;
        }

        pid = fork();
        if (pid < 0) {
            LOGE("fork failed for pty, error %d", errno);
            close(fdMaster);
            pid = 0;
            return false;
        } else if (pid) {
            // child started, now someone needs to periodically read from fdMaster
            // and write it to the terminal
            // this currently works through gui.cpp calling terminal_pty_read below
            g_pty_fd = fdMaster;
            return true;
        } else {
            int fdSlave = open(ptsname(fdMaster), O_RDWR);
            close(fdMaster);
            runSlave(fdSlave);
        }
        // we can't get here
        LOGE("impossible error in pty");
        return false;
    }
Example #2
0
/*
 * test hangup semantics
 */
int
test6(void)
{
	static int masterfd;
	static int slavefd;
	char *slavename;
	struct termios termios;

	masterfd = open(MASTERCLONE, O_RDWR);
	if (masterfd < 0) {
		tst_resm(TBROK,"%s",MASTERCLONE);
		tst_exit();
	}

	slavename = ptsname(masterfd);
	if (slavename == NULL) {
		tst_resm(TBROK|TERRNO, "ptsname() call failed");
		tst_exit();
	}

	if (grantpt(masterfd) != 0) {
		tst_resm(TBROK|TERRNO, "grantpt() call failed");
		tst_exit();
	}

	if (unlockpt(masterfd) != 0) {
		tst_resm(TBROK,"unlockpt() call failed");
		tst_exit();
	}

	if ((slavefd = open(slavename, O_RDWR)) < 0) {
		tst_resm(TBROK,"Could not open %s",slavename);
		tst_exit();
	}

	if (ioctl(slavefd, TCGETS, &termios) != 0) {
		tst_resm(TFAIL,"TCGETS");
		tst_exit();
	}

	termios.c_cflag &= ~CBAUD;
	termios.c_cflag |= B0&CBAUD;
	if (ioctl(slavefd, TCSETS, &termios) != 0) {
		tst_resm(TFAIL,"TCGETS");
		tst_exit();
	}

	if (close(slavefd) != 0) {
		tst_resm(TBROK,"close");
		tst_exit();
	}
	if (close(masterfd) != 0) {
		tst_resm(TBROK,"close");
		tst_exit();
	}
	tst_resm(TPASS,"test6");

	/** NOT REACHED **/
	return 0;
}
Example #3
0
gint
ide_vte_pty_create_slave (VtePty *pty)
{
  gint master_fd;
#ifdef HAVE_PTSNAME_R
  char name[PATH_MAX + 1];
#else
  const char *name;
#endif

  g_assert (VTE_IS_PTY (pty));

  if (-1 == (master_fd = vte_pty_get_fd (pty)))
    return -1;

  if (grantpt (master_fd) != 0)
    return -1;

  if (unlockpt (master_fd) != 0)
    return -1;

#ifdef HAVE_PTSNAME_R
  if (ptsname_r (master_fd, name, sizeof name - 1) != 0)
    return -1;
  name[sizeof name - 1] = '\0';
#else
  if (NULL == (name = ptsname (master_fd)))
    return -1;
#endif

  return open (name, O_RDWR | O_CLOEXEC);
}
Example #4
0
int open_pty_pair(int *masterp, int *slavep)
{
	int master, slave;
	char name[1024];

	master = getpt();
	if (master < 0) {
		return 0;
	}

	if (grantpt(master) < 0 || unlockpt(master) < 0) {
		close(master);
		return 0;
	}

	if (ptsname_r(master, name, sizeof(name)) < 0) {
		close(master);
		return 0;
	}

	slave = open(name, O_RDWR);
	if (slave < 0) {
		close(master);
		return 0;
	}

	*masterp = master;
	*slavep = slave;
	return 1;
}
Example #5
0
int
ptym_open(char *pts_name)
{
	char	*ptr;
	int		fdm;

	strcpy(pts_name, "/dev/ptmx");	/* in case open fails */
	if ( (fdm = open(pts_name, O_RDWR)) < 0)
		return(-1);

	if (grantpt(fdm) < 0) {		/* grant access to slave */
		close(fdm);
		return(-2);
	}
	if (unlockpt(fdm) < 0) {	/* clear slave's lock flag */
		close(fdm);
		return(-3);
	}
	if ( (ptr = ptsname(fdm)) == NULL) {	/* get slave's name */
		close(fdm);
		return(-4);
	}

	strcpy(pts_name, ptr);	/* return name of slave */
	return(fdm);			/* return fd of master */
}
Example #6
0
static int
test_ebadf (void)
{
  int fd, ret, err;

  fd = posix_openpt (O_RDWR);
  if (fd == -1)
    {
      printf ("posix_openpt(O_RDWR) failed\nerrno %d (%s)\n",
	      errno, strerror (errno));
      /* We don't fail because of this; maybe the system does not have
	 SUS pseudo terminals.  */
      return 0;
    }
  unlockpt (fd);
  close (fd);

  ret = grantpt (fd);
  err = errno;
  if (ret != -1 || err != EBADF)
    {
      printf ("grantpt(): expected: return = %d, errno = %d\n", -1, EBADF);
      printf ("           got: return = %d, errno = %d\n", ret, err);
      return 1;
    }
  return 0;
}
Example #7
0
static int
pty_open_master (char *pty_name)
{
    char *slave_name;
    int pty_master;

#ifdef HAVE_POSIX_OPENPT
    pty_master = posix_openpt (O_RDWR);
#elif defined HAVE_GETPT
    /* getpt () is a GNU extension (glibc 2.1.x) */
    pty_master = getpt ();
#elif defined IS_AIX
    strcpy (pty_name, "/dev/ptc");
    pty_master = open (pty_name, O_RDWR);
#else
    strcpy (pty_name, "/dev/ptmx");
    pty_master = open (pty_name, O_RDWR);
#endif

    if (pty_master == -1)
        return -1;

    if (grantpt (pty_master) == -1      /* Grant access to slave */
        || unlockpt (pty_master) == -1  /* Clear slave's lock flag */
        || !(slave_name = ptsname (pty_master)))        /* Get slave's name */
    {
        close (pty_master);
        return -1;
    }
    strcpy (pty_name, slave_name);
    return pty_master;
}
Example #8
0
int io_init(void)
{
	struct termios io;

	if(!iobuffer) {
		iobuffer = malloc(IOBSZ);
		head = tail = 0;
	}

	// init serial
	bzero(&io, sizeof(struct termios));
	io.c_cflag |= CLOCAL | CREAD;
	io.c_cflag &= ~CSIZE;
	io.c_cflag |= CS8;
	io.c_cflag &= ~PARENB;
	io.c_cflag &= ~CSTOPB;
	cfsetispeed(&io, B115200);
	cfsetospeed(&io, B115200);

	iofd = open(TTYDEV, O_RDWR | O_NOCTTY | O_NDELAY);

	unlockpt(iofd);
	grantpt(iofd);

	if(iofd >= 0) {
		tcflush(iofd, TCIFLUSH);
		if(tcsetattr(iofd, TCSANOW, &io) != 0)
			return -2;
	}

	return iofd;
}
Example #9
0
/* allocate one pty/tty pair (Unix 98 way) */
static int get_pty(char *tty_buf, int tty_buf_size)
{
#ifdef ZIPIT_Z2
    return get_pty_old(tty_buf, tty_buf_size);
#else
    int fd;
    char *str;

    fd = posix_openpt(O_RDWR | O_NOCTTY);
    if (fd < 0) {
        return get_pty_old(tty_buf, tty_buf_size);
    }
    if (grantpt(fd) < 0)
        goto fail;
    if (unlockpt(fd) < 0)
        goto fail;
    str = ptsname(fd);
    if (!str)
        goto fail;
    pstrcpy(tty_buf, tty_buf_size, str);
    return fd;
 fail:
    close(fd);
    return -1;
#endif
}
Example #10
0
File: get_pty.c Project: CVi/sudo
int
get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
{
    char *line;

    *master = posix_openpt(O_RDWR|O_NOCTTY);
    if (*master == -1)
	return 0;

    (void) grantpt(*master); /* may fork */
    if (unlockpt(*master) != 0) {
	close(*master);
	return 0;
    }
    line = ptsname(*master);
    if (line == NULL) {
	close(*master);
	return 0;
    }
    *slave = open(line, O_RDWR|O_NOCTTY, 0);
    if (*slave == -1) {
	close(*master);
	return 0;
    }
# if defined(I_PUSH) && !defined(_AIX)
    ioctl(*slave, I_PUSH, "ptem");	/* pseudo tty emulation module */
    ioctl(*slave, I_PUSH, "ldterm");	/* line discipline module */
# endif
    (void) chown(line, ttyuid, -1);
    strlcpy(name, line, namesz);
    return 1;
}
Example #11
0
static int _openpty(int *amaster, int *aslave) {

    int master = -1, slave = -1;
    char *slave_name;
    static const char *fn[] = { "/dev/ptmx", "/dev/ptc", 0 };
    long long i;

    for (i = 0; fn[i]; ++i) {
        master = open(fn[i], O_RDWR | O_NOCTTY);
        if (master != -1) break;
    }
    if (master == -1) return -1;

    if (grantpt(master) == -1) { close(master); return -1; }
    if (unlockpt(master) == -1) { close(master); return -1; }
    slave_name = ptsname(master);
    if (!slave_name) { close(master); return -1; }
    slave = open(slave_name, O_RDWR | O_NOCTTY);
    if (slave == -1) { close(master); return -1; }
#if defined(sun) || defined(__hpux)
    ioctl(slave, I_PUSH, "ptem");
    ioctl(slave, I_PUSH, "ldterm");
#endif
#if defined(sun)
    ioctl(slave, I_PUSH, "ttcompat");
#endif

    if (amaster) *amaster = master;
    if (aslave)  *aslave  = slave;
    return 0;
}
Example #12
0
File: pty.c Project: gbl/vte
static gboolean
_vte_pty_unlockpt(int fd,
                  GError **error)
{
        int rv;
#ifdef HAVE_UNLOCKPT
	rv = unlockpt(fd);
        if (rv != 0) {
                int errsv = errno;
                g_set_error(error, VTE_PTY_ERROR, VTE_PTY_ERROR_PTY98_FAILED,
                            "%s failed: %s", "unlockpt", g_strerror(errsv));
                errno = errsv;
                return FALSE;
        }
        return TRUE;
#elif defined(TIOCSPTLCK)
	int zero = 0;
	rv = ioctl(fd, TIOCSPTLCK, &zero);
        if (rv != 0) {
                int errsv = errno;
                g_set_error(error, VTE_PTY_ERROR, VTE_PTY_ERROR_PTY98_FAILED,
                            "%s failed: %s", "ioctl(TIOCSPTLCK)", g_strerror(errsv));
                errno = errsv;
                return FALSE;
        }
        return TRUE;
#else
#error no unlockpt implementation for this platform
#endif
}
Example #13
0
TEST(stdlib, unlockpt_ENOTTY) {
  int fd = open("/dev/null", O_WRONLY);
  errno = 0;
  ASSERT_EQ(-1, unlockpt(fd));
  ASSERT_EQ(ENOTTY, errno);
  close(fd);
}
Example #14
0
void handle_signals_resets_terminal(void)
{
	int status, masterfd;
	char* slavedevice = NULL;
	struct termios test_flags;
	pid_t child_pid;

	masterfd = posix_openpt(O_RDWR|O_NOCTTY);

	if (masterfd == -1
		|| grantpt (masterfd) == -1
		|| unlockpt (masterfd) == -1
		|| (slavedevice = ptsname (masterfd)) == NULL)
		CU_FAIL_FATAL("Could not create pty");

	terminal_fildes = open(slavedevice, O_RDWR|O_NOCTTY);
	tcgetattr(terminal_fildes, &orig_flags);
	new_flags = orig_flags;
	new_flags.c_lflag &= ~ECHO;
	tcsetattr(terminal_fildes, TCSANOW, &new_flags);
	terminal_needs_reset = 1;

	if((child_pid = fork()) == 0)
	{
		freerdp_handle_signals();
		raise(SIGINT);
	}
	while(wait(&status) != -1);
	tcgetattr(terminal_fildes, &test_flags);
	CU_ASSERT_EQUAL(orig_flags.c_lflag, test_flags.c_lflag);
	close(masterfd);
	close(terminal_fildes);
}
Example #15
0
/***
Unlock a pseudoterminal master/slave pair
@function unlockpt
@int fd descriptor returned by openpt
@treturn[1] int `0`, if successful
@return[2] nil
@treturn[2] string error message
@treturn[2] int errnum
@see unlockpt(3)
@see openpt
@see ptsname
@see grantpt
*/
static int
Punlockpt(lua_State *L)
{
	int fd=checkint(L, 1);
	checknargs(L, 1);
	return pushresult(L, unlockpt(fd), "unlockpt");
}
Example #16
0
    int
OpenPTY(char **ttyn)
{
    int		f;
    char	*m;
    char	*(ptsname(int));
    int		unlockpt(int);
    int		grantpt(int);
    RETSIGTYPE (*sigcld) SIGPROTOARG;
    /* used for opening a new pty-pair: */
    static char TtyName[32];

    if ((f = open("/dev/ptmx", O_RDWR | O_NOCTTY | O_EXTRA, 0)) == -1)
	return -1;

    /*
     * SIGCHLD set to SIG_DFL for grantpt() because it fork()s and
     * exec()s pt_chmod
     */
    sigcld = signal(SIGCHLD, SIG_DFL);
    if ((m = ptsname(f)) == NULL || grantpt(f) || unlockpt(f))
    {
	signal(SIGCHLD, sigcld);
	close(f);
	return -1;
    }
    signal(SIGCHLD, sigcld);
    vim_strncpy((char_u *)TtyName, (char_u *)m, sizeof(TtyName) - 1);
    initmaster(f);
    *ttyn = TtyName;
    return f;
}
Example #17
0
int
allocate_pty(int *master, int *slave) {
#if defined(HAVE_OPENPTY) || (defined(HAVE_DECL_OPENPTY) && HAVE_DECL_OPENPTY != 0)
  if(openpty(master, slave, NULL, NULL, NULL)) return -1;
#else
  /* STREAMS... sigh */
  char   *slavename;
  extern char *ptsname();

  *master = open("/dev/ptmx", O_RDWR);  /* open master */
  if(*master < 0) return -1;
  grantpt(*master);                     /* change permission of   slave */
  unlockpt(*master);                    /* unlock slave */
  slavename = ptsname(*master);         /* get name of slave */
  *slave = open(slavename, O_RDWR);    /* open slave */
  if(*slave < 0) {
    close(*master);
    *master = -1;
    return -1;
  }
  /* This is a bit backwards as we using the PTY backwards.
   * We want to make the master a tty instead of the slave... odd, I know.
   */
  ioctl(*master, I_PUSH, "ptem");       /* push ptem */
  ioctl(*master, I_PUSH, "ldterm");     /* push ldterm*/
#endif
  if(eventer_set_fd_nonblocking(*master)) return -1;
  noitL(noit_debug, "allocate_pty -> %d,%d\n", *master, *slave);
  return 0;
}
Example #18
0
int get_pty(Term *term)
{
   /* do we need this here? */
   /* extern char *ptsname(); */
   int fd;
   char *ptydev;

   if((fd = getpt()) >= 0)
     {
	if(grantpt(fd) == 0 && unlockpt(fd) == 0)
	  {
	     ptydev = ptsname(fd);
	     if((term->slave.sys = open(ptydev, O_RDWR | O_NOCTTY)) < 0)
	       {
		  fprintf(stderr, "Error opening slave pty: %m\n");
		  return -1;
	       }
	     fcntl(fd, F_SETFL, O_NDELAY);
	     return fd;
	  }
	close(fd);
     }
   fprintf(stderr, "Can't open a pseudo-tty\n");
   return -1;
}
Example #19
0
int ptym_open(char *pts_name)
{
    char *ptr;
    int  fdm;
#if defined(AIX43) || defined(AIX51)
    char default_pts_name[] = "/dev/ptc";
#else
    char default_pts_name[] = "/dev/ptmx";
#endif

    strcpy(pts_name, default_pts_name);   /* in case open fails */
    if ((fdm = open(pts_name, O_RDWR)) < 0) {
        return -1;
    }

    if (grantpt(fdm) < 0) {    /* grant access to slave */
        close(fdm);
        return -2;
    }
    if (unlockpt(fdm) < 0) {   /* clear slave's lock flag */
        close(fdm);
        return -3;
    }
    if ((ptr = ptsname(fdm)) == NULL) {   /* get slave's name */
        close(fdm);
        return -4;
    }

    strcpy(pts_name, ptr);  /* return name of slave */
    return fdm;             /* return fd of master */
}
Example #20
0
int get_pty(void)
{
    struct grantpt_info info;
    int fd, err;

    fd = open("/dev/ptmx", O_RDWR);
    if (fd < 0) {
        err = -errno;
        printk(UM_KERN_ERR "get_pty : Couldn't open /dev/ptmx - "
               "err = %d\n", errno);
        return err;
    }

    info.fd = fd;
    initial_thread_cb(grantpt_cb, &info);

    if (info.res < 0) {
        err = -info.err;
        printk(UM_KERN_ERR "get_pty : Couldn't grant pty - "
               "errno = %d\n", -info.err);
        goto out;
    }

    if (unlockpt(fd) < 0) {
        err = -errno;
        printk(UM_KERN_ERR "get_pty : Couldn't unlock pty - "
               "errno = %d\n", errno);
        goto out;
    }
    return fd;
out:
    close(fd);
    return err;
}
Example #21
0
int open_pty() {
  int fd = check("posix_openpt", posix_openpt(O_RDWR | O_NOCTTY));
  check("grantpt",  grantpt(fd));
  check("unlockpt", unlockpt(fd));

  return fd;
}
Example #22
0
int
GUCEF_pty_open( int* fdm, int* fds )
{
    int masterfd, slavefd;
    char *slavedevice;

    /*
     *  O_RDWR = Open the device for both reading and writing. It is usual to specify this flag.
     *  O_NOCTTY = Do not make this device the controlling terminal for the process.
     */
    masterfd = posix_openpt( O_RDWR | O_NOCTTY );

    if ( masterfd == -1 ||
         grantpt (masterfd) == -1 ||
         unlockpt (masterfd) == -1 ||
         (slavedevice = ptsname (masterfd)) == NULL)
        return 1;

    slavefd = open(slavedevice, O_RDWR|O_NOCTTY);
    if (slavefd < 0)
        return 1;

    /* success */
    *fdm = masterfd;
    *fds = slavefd;
    return 0;
}
Example #23
0
int openpty(int* master, int* slave, char* name, const termios* t, const winsize* ws) {
  *master = getpt();
  if (*master == -1) {
    return -1;
  }

  if (grantpt(*master) == -1 || unlockpt(*master) == -1) {
    close(*master);
    return -1;
  }

  char buf[32];
  if (name == NULL) {
    name = buf;
  }
  if (ptsname_r(*master, name, sizeof(buf)) != 0) {
    close(*master);
    return -1;
  }

  *slave = open(name, O_RDWR|O_NOCTTY);
  if (*slave == -1) {
    close(*master);
    return -1;
  }

  if (t != NULL) {
    tcsetattr(*slave, TCSAFLUSH, t);
  }
  if (ws != NULL) {
    ioctl(*slave, TIOCSWINSZ, ws);
  }

  return 0;
}
Example #24
0
static int
ptym_open(char *pts_name)
{
    char	*ptr;
    int		fdm;

    strcpy(pts_name, "/dev/ptmx");
    if ((fdm = open(pts_name, O_RDWR)) < 0)
	return(-1);
    if (grantpt(fdm) < 0) {
	close(fdm);
	return(-1);
    }
    if (unlockpt(fdm) < 0) {
	close(fdm);
	return(-1);
    }
    if ((ptr = ptsname(fdm)) == NULL) {
	close(fdm);
	return(-1);
    }

    strcpy(pts_name, ptr);
    return(fdm);
}
Example #25
0
/*
 * Allocate pty master (APUE, p. 638).
 */
int
ptym_open(char *pts_name, size_t namsz)
{
	char *ptr;
	int fdm;

	strcpy(pts_name, "/dev/ptmx");
	if ((fdm = open(pts_name, O_RDWR)) < 0)
		return -1;
	if (grantpt(fdm) < 0) {
		close(fdm);
		return -2;
	}
	if (unlockpt(fdm) < 0) {
		close(fdm);
		return -3;
	}
	if ((ptr = ptsname(fdm)) == NULL) {
		close(fdm);
		return -4;
	}
	strncpy(pts_name, ptr, namsz);
#ifndef	__linux__
	if (ioctl(fdm, I_PUSH, "pckt") < 0) {
		close(fdm);
		return -5;
	}
#endif	/* !__linux__ */
	return fdm;
}
int ptym_open(char *pts_name, int pts_namesz)
{
    char *ptr;
    int fdm;

    /*
     * Return the name of the master device so that on failure
     * the caller can print an error message. Null terminate
     * to handle case where string length > pts_namesz.
     */
    strncpy(pts_name, "/dev/ptyXY", pts_namesz);
    pts_name[pts_namesz - 1] = '\0';
    if ((fdm = posix_openpt(O_RDWR)) < 0)
        return(-1);
    if (grantpt(fdm) < 0) {     /* grant access to slave */
        close(fdm);
        return(-2);
    }
    if (unlockpt(fdm) < 0) {    /* clear slave's lock flag */
        close(fdm);
        return(-3);
    }
    if ((ptr = ptsname(fdm)) == NULL) {     /* get slave's name */
        close(fdm);
        return(-4);
    }

    /*
     * Return name of slave. Null terminate to handle
     * case where strlen(ptr) > pts_namesz.
     */
    strncpy(pts_name, ptr, pts_namesz);
    pts_name[pts_namesz - 1] = '\0';
    return(fdm);    /* return fd of master */
}
Example #27
0
int open_master(char *name, int sz) {
  char *sname;
  int fd;

  strncpy(name, DEV_PTMX, sz);
  name[sz - 1] = '\0';

  fd = open(name, O_RDWR);
  if (fd < 0)
    return EPTMX_OPEN;

  if (grantpt(fd) < 0) {
    close(fd);
    return EPTMX_GRANT;
  }

  if (unlockpt(fd) < 0) {
    close(fd);
    return EPTMX_UNLOCK;
  }

  sname = ptsname(fd);
  if (sname == NULL) {
    close(fd);
    return EPTMX_NAME;
  }

  strncpy(name, sname, sz);
  name[sz - 1] = '\0';
  return fd;
}
Example #28
0
int
ptym_open(char * pts_name)
{
	int fdm;
	char *ptr;

	strcpy(pts_name, "/dev/ptmx");
	fdm = posix_openpt(O_RDWR);
	if (fdm < 0)
		return -1;
	if (grantpt(fdm) < 0) { /* grant access to slave */
		close(fdm);
		return -2;
	}
	if (unlockpt(fdm) < 0) { /* clear slave's lock flag */
		close(fdm);
		return -3;
	}
	ptr = ptsname(fdm);
	if (ptr == NULL) { /* get slave's name */
		close (fdm);
		return -4;
	}
	strcpy(pts_name, ptr); /* return name of slave */
	return fdm;            /* return fd of master */
}
Example #29
0
int main(void) {
	int fdm;
	int rc;

	// initial
	system("ls -l /dev/pts");

	fdm = posix_openpt(O_RDWR);
	if (fdm < 0) {
		perror("posix_openpt");
		return 1;
	}

	rc = grantpt(fdm);
	if (rc != 0) {
		perror("grantpt");
		return 1;
	}

	rc = unlockpt(fdm);
	if (rc != 0) {
		perror("unlockpt");
		return 1;
	}

	// final
	system("ls -l /dev/pts");

	return 0;
}
Example #30
0
/*
 * Check that the given PTY index, which is in use for an old-style PTY, is not
 * allocated through Unix98 PTY allocation.  This test is not foolproof, but it
 * does the job well enough.
 */
static void
test_overlap(int m)
{
    char *tname;
    size_t len;
    int i, n, fd[MIN_PTYS];

    for (i = 0; i < MIN_PTYS; i++) {
        if ((fd[i] = posix_openpt(O_RDWR | O_NOCTTY)) < 0)
            break; /* out of PTYs */
        if (grantpt(fd[i]) < 0) e(0);
        if (unlockpt(fd[i]) < 0) e(0);
        if ((tname = ptsname(fd[i])) == NULL) e(0);

        len = strlen(_PATH_DEV_PTS);
        if (strncmp(tname, _PATH_DEV_PTS, strlen(_PATH_DEV_PTS))) e(0);
        n = atoi(&tname[len]);
        if (n < 0 || n > 9) e(0);

        if (m == n) e(0);
    }

    for (i--; i >= 0; i--)
        if (close(fd[i]) < 0) e(0);
}