int ttyname_r (int fd, char *buf, size_t buflen) #undef ttyname_r { /* When ttyname_r exists, use it. */ #if HAVE_TTYNAME_R /* This code is multithread-safe. */ /* On Solaris, ttyname_r always fails if buflen < 128. On OSF/1 5.1, ttyname_r ignores the buffer size and assumes the buffer is large enough. So provide a buffer that is large enough. */ char largerbuf[512]; # if HAVE_POSIXDECL_TTYNAME_R int err = (buflen < sizeof (largerbuf) ? ttyname_r (fd, largerbuf, sizeof (largerbuf)) : ttyname_r (fd, buf, buflen <= INT_MAX ? buflen : INT_MAX)); if (err != 0) return err; if (buflen < sizeof (largerbuf)) { size_t namelen = strlen (largerbuf) + 1; if (namelen > buflen) return ERANGE; memcpy (buf, largerbuf, namelen); } # else char *name = (buflen < sizeof (largerbuf) ? ttyname_r (fd, largerbuf, sizeof (largerbuf)) : ttyname_r (fd, buf, buflen <= INT_MAX ? buflen : INT_MAX)); if (name == NULL) return errno; if (name != buf) { size_t namelen = strlen (name) + 1; if (namelen > buflen) return ERANGE; memmove (buf, name, namelen); } # endif return 0; #elif HAVE_TTYNAME /* Note: This is not multithread-safe. */ char *name; size_t namelen; name = ttyname (fd); if (name == NULL) return errno; namelen = strlen (name) + 1; if (namelen > buflen) return ERANGE; memcpy (buf, name, namelen); return 0; #else /* Platforms like mingw: no ttys exist at all. */ return ENOTTY; #endif }
bool is_same_tty(FILE *f1, FILE *f2) { #if HAVE_TTYNAME return ttyname_r(fileno(f1), LOCAL_FileNameBuf, YAP_FILENAME_MAX - 1) == ttyname_r(fileno(f2), LOCAL_FileNameBuf, YAP_FILENAME_MAX - 1); #endif // assume a single console, for now return true; }
explicit GnuplotPty(bool debug_messages) : pty_fn(), pty_fh(NULL), master_fd(-1), slave_fd(-1) { // adapted from http://www.gnuplot.info/files/gpReadMouseTest.c if(0 > openpty(&master_fd, &slave_fd, NULL, NULL, NULL)) { perror("openpty"); throw std::runtime_error("openpty failed"); } char pty_fn_buf[1024]; if(ttyname_r(slave_fd, pty_fn_buf, 1024)) { perror("ttyname_r"); throw std::runtime_error("ttyname failed"); } pty_fn = std::string(pty_fn_buf); if(debug_messages) { std::cerr << "fn=" << pty_fn << std::endl; } // disable echo struct termios tios; if(tcgetattr(slave_fd, &tios) < 0) { perror("tcgetattr"); throw std::runtime_error("tcgetattr failed"); } tios.c_lflag &= ~(ECHO | ECHONL); if(tcsetattr(slave_fd, TCSAFLUSH, &tios) < 0) { perror("tcsetattr"); throw std::runtime_error("tcsetattr failed"); } pty_fh = fdopen(master_fd, "r"); if(!pty_fh) throw std::runtime_error("fdopen failed"); }
int getttyname_malloc(int fd, char **ret) { size_t l = 100; int r; assert(fd >= 0); assert(ret); for (;;) { char path[l]; r = ttyname_r(fd, path, sizeof(path)); if (r == 0) { const char *p; char *c; p = startswith(path, "/dev/"); c = strdup(p ?: path); if (!c) return -ENOMEM; *ret = c; return 0; } if (r != ERANGE) return -r; l *= 2; } return 0; }
uintptr_t REG_POLY_FUN_HDR(sml_ttyname, uintptr_t pair, Region rs, int fd) { char *buf; int i = 100, r; fd = convertIntToC(fd); mkTagPairML(pair); r = 0; if (r == ERANGE) r++; do { buf = (char *) malloc(i); if (!buf) { first(pair) = convertIntToML(errno); second(pair) = (uintptr_t) NULL; } buf[i-1] = 0; r = ttyname_r(fd, buf, i-1); if (r == 0) { first(pair) = convertIntToML(0); second(pair) = (uintptr_t) REG_POLY_CALL(convertStringToML, rs, buf); free(buf); return pair; } r = errno; free(buf); i <<= 1; } while (r == ERANGE); first(pair) = convertIntToML(r); second(pair) = (uintptr_t) NULL; return pair; }
char * ttyname(int fd) { char *buf; if (thr_main() != 0) buf = ttyname_buf; else { if (thr_once(&ttyname_init_once, ttyname_keycreate) != 0 || !ttyname_keycreated) return (NULL); if ((buf = thr_getspecific(ttyname_key)) == NULL) { if ((buf = malloc(sizeof ttyname_buf)) == NULL) return (NULL); if (thr_setspecific(ttyname_key, buf) != 0) { free(buf); return (NULL); } } } if (ttyname_r(fd, buf, sizeof ttyname_buf) != 0) return (NULL); return (buf); }
static int setup_xenconsoled_pty(libxl__egc *egc, libxl__bootloader_state *bl, char *slave_path, size_t slave_path_len) { STATE_AO_GC(bl->ao); struct termios termattr; int r, rc; int slave = libxl__carefd_fd(bl->ptys[1].slave); int master = libxl__carefd_fd(bl->ptys[1].master); r = ttyname_r(slave, slave_path, slave_path_len); if (r == -1) { LOGE(ERROR,"ttyname_r failed"); rc = ERROR_FAIL; goto out; } /* * On Solaris, the pty master side will get cranky if we try * to write to it while there is no slave. To work around this, * keep the slave descriptor open until we're done. Set it * to raw terminal parameters, otherwise it will echo back * characters, which will confuse the I/O loop below. * Furthermore, a raw master pty device has no terminal * semantics on Solaris, so don't try to set any attributes * for it. */ tcgetattr(master, &termattr); cfmakeraw(&termattr); tcsetattr(master, TCSANOW, &termattr); return 0; out: return rc; }
static s32 open_gpm(Gpm_Connect *conn) { s8 buf[64]; s32 ret = ttyname_r(STDIN_FILENO, buf, sizeof(buf)); u32 index = strlen(buf) - 1; while (buf[index] >= '0' && buf[index] <= '9') index--; s8 *tail; conn->vc = strtol(buf + index + 1, &tail, 10); if (*tail) return -1; conn->pid = getpid(); s32 gpm_fd = socket(PF_UNIX, SOCK_STREAM, 0); if (gpm_fd == -1) return -1; struct sockaddr_un addr; memset((s8 *)&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, GPM_NODE_CTL, sizeof(addr.sun_path) - 1); #define OFFSET(TYPE, MEMBER) ((size_t)(&(((TYPE *)0)->MEMBER))) u32 len = OFFSET(sockaddr_un, sun_path) + sizeof(GPM_NODE_CTL) - 1; if (len > sizeof(addr)) len = sizeof(addr); if(connect(gpm_fd, (struct sockaddr *)(&addr), len) < 0 || write(gpm_fd, conn, sizeof(*conn)) != sizeof(*conn)) { close(gpm_fd); return -1; } return gpm_fd; }
/* * SNOOPY FILTER: only_tty * * Description: * Returns TTY of current process. * * Params: * result: pointer to string, to write result into * arg: (ignored) * * Return: * number of characters in the returned string, or SNOOPY_DATASOURCE_FAILURE */ int snoopy_filter_only_tty(char *msg, char const * const arg) { char ttyPath[SNOOPY_DATASOURCE_TTY_sizeMaxWithNull]; size_t ttyPathLen = SNOOPY_DATASOURCE_TTY_sizeMaxWithoutNull; int retVal = ttyname_r(0, ttyPath, ttyPathLen); return (ENOTTY == retVal) ? SNOOPY_FILTER_DROP : SNOOPY_FILTER_PASS; }
int ttyslot(void) { struct futmpx ubuf; char *p; int s; int ret = -1; int console = FALSE; char ttynm[128]; FILE *fp; int cancel_state; /* * The UNIX98 Posix conformance test suite requires * ttyslot() to not be a cancellation point. */ (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state); if ((p = ttyname_r(0, ttynm, 128)) != NULL || (p = ttyname_r(1, ttynm, 128)) != NULL || (p = ttyname_r(2, ttynm, 128)) != NULL) { if (strncmp(p, "/dev/", 5) == 0) p += 5; if (strcmp(p, "console") == 0) console = TRUE; s = 0; if ((fp = fopen(UTMPX_FILE, "rF")) != NULL) { while ((fread(&ubuf, sizeof (ubuf), 1, fp)) == 1) { if ((ubuf.ut_type == INIT_PROCESS || ubuf.ut_type == LOGIN_PROCESS || ubuf.ut_type == USER_PROCESS) && strncmp(p, ubuf.ut_line, sizeof (ubuf.ut_line)) == 0) { ret = s; if (!console || strncmp(ubuf.ut_host, ":0", 2) == 0) break; } s++; } (void) fclose(fp); } } (void) pthread_setcancelstate(cancel_state, NULL); return (ret); }
TEST(stdlib, ttyname_r_ENOTTY) { int fd = open("/dev/null", O_WRONLY); errno = 0; char buf[128]; ASSERT_EQ(ENOTTY, ttyname_r(fd, buf, sizeof(buf))); ASSERT_EQ(ENOTTY, errno); close(fd); }
int main() { char buffer[256]; int d = open("/device", O_RDWR); int f = open("/", O_RDONLY); char* result; result = ctermid(buffer); if (result) { printf("ctermid: %s\n", result); } else { printf("ctermid errno: %d\n", errno); errno = 0; } if (ttyname_r(d, buffer, 256) == 0) { printf("ttyname_r(d, ..., 256): %s\n", buffer); } else { printf("ttyname_r(d, ..., 256) errno: %d\n", errno); errno = 0; } if (ttyname_r(d, buffer, 2) == 0) { printf("ttyname_r(d, ..., 2): %s\n", buffer); } else { printf("ttyname_r(d, ..., 2) errno: %d\n", errno); errno = 0; } result = ttyname(d); if (result) { printf("ttyname(d): %s\n", result); } else { printf("ttyname(d) errno: %d\n", errno); errno = 0; } result = ttyname(f); if (result) { printf("ttyname(f): %s\n", result); } else { printf("ttyname(f) errno: %d\n", errno); errno = 0; } return 0; }
TEST(stdlib, ttyname_r_EINVAL) { int fd = getpt(); ASSERT_NE(-1, fd); errno = 0; char* buf = NULL; ASSERT_EQ(EINVAL, ttyname_r(fd, buf, 128)); ASSERT_EQ(EINVAL, errno); close(fd); }
TEST(stdlib, ttyname_r_ERANGE) { int fd = getpt(); ASSERT_NE(-1, fd); errno = 0; char buf[1]; ASSERT_EQ(ERANGE, ttyname_r(fd, buf, sizeof(buf))); ASSERT_EQ(ERANGE, errno); close(fd); }
static int do_test (void) { int ret = 0; char buf[sysconf (_SC_TTY_NAME_MAX) + 1]; int res = ttyname_r (-1, buf, sizeof (buf)); if (res != EBADF) { printf ("1st ttyname_r returned with res %d\n", res); ret++; } res = ttyname_r (temp_fd, buf, sizeof (buf)); if (res != ENOTTY) { printf ("2nd ttyname_r returned with res %d\n", res); ret++; } return ret; }
char* FAST_FUNC xmalloc_ttyname(int fd) { char *buf = xzalloc(128); int r = ttyname_r(fd, buf, 127); if (r) { free(buf); buf = NULL; } return buf; }
char *ttyname(int fd) { static char buf[TTY_NAME_MAX]; int result; if ((result = ttyname_r(fd, buf, sizeof buf))) { errno = result; return NULL; } return buf; }
TEST(stdlib, ttyname_r) { int fd = getpt(); ASSERT_NE(-1, fd); // ttyname_r returns "/dev/ptmx" for a pty. char name_r[128]; ASSERT_EQ(0, ttyname_r(fd, name_r, sizeof(name_r))); ASSERT_STREQ("/dev/ptmx", name_r); close(fd); }
//## String System.ttyname(int fd); static KMETHOD System_ttyname(KonohaContext *kctx, KonohaStack *sfp) { int fd = sfp[1].intValue; char buf[K_PAGESIZE]; int ret = ttyname_r(fd, buf, sizeof(buf)); if(ret != 0) { KMakeTrace(trace, sfp); int fault = KLIB DiagnosisFaultType(kctx, SystemError, trace); KTraceErrorPoint(trace, fault, "ttyname", LogUint("fd", fd), LogErrno); } KReturn(KLIB new_kString(kctx, OnStack, buf, strlen(buf), 0)); }
/** * give the name of a tty fd. * @param fd the tty to get the name from. * @return the name of the tty or NULL on error. */ char * ttyname(int fd) { static char pathname[MAXPATHLEN]; int err = ttyname_r(fd, pathname, sizeof(pathname)); if (err != 0) { __set_errno(err); return NULL; } return pathname; }
Variant f_posix_ttyname(CVarRef fd) { int ttyname_maxlen = sysconf(_SC_TTY_NAME_MAX); if (ttyname_maxlen <= 0) { return false; } String ttyname(ttyname_maxlen, ReserveString); char *p = ttyname.mutableSlice().ptr; if (ttyname_r(php_posix_get_fd(fd), p, ttyname_maxlen)) { return false; } return ttyname.setSize(strlen(p)); }
/* Write the given entry into utmp and wtmp. * Note: the match in utmp is done against ut_id field, * which is NOT set by this function - caller must set it. */ void login(const struct utmp *entry) { struct utmp copy; char tty_name[sizeof(copy.ut_line) + 6]; int fd; // Manpage: // login() takes the argument ut struct, fills the field ut->ut_type // (if there is such a field) with the value USER_PROCESS, // and fills the field ut->ut_pid (if there is such a field) // with the process ID of the calling process. copy = *entry; #if _HAVE_UT_TYPE - 0 copy.ut_type = USER_PROCESS; #endif #if _HAVE_UT_PID - 0 copy.ut_pid = getpid(); #endif // Then it tries to fill the field ut->ut_line. It takes the first of stdin, // stdout, stderr that is a tty, and stores the corresponding pathname minus // a possible leading /dev/ into this field, and then writes the struct // to the utmp file. On the other hand, if no tty name was found, // this field is filled with "???" and the struct is not written // to the utmp file. fd = 0; while (fd != 3 && ttyname_r(fd, tty_name, sizeof(tty_name)) != 0) fd++; if (fd != 3) { if (strncmp(tty_name, "/dev/", 5) == 0) strncpy(copy.ut_line, tty_name + 5, sizeof(copy.ut_line)-1); else strncpy(copy.ut_line, tty_name, sizeof(copy.ut_line)-1); copy.ut_line[sizeof(copy.ut_line)-1] = '\0'; /* utmpname(_PATH_UTMP); - why? * this makes it impossible for caller to use other file! * Does any standard or historical precedent says this must be done? */ setutent(); /* Replaces record with matching ut_id, or appends new one: */ pututline(©); endutent(); } else { strncpy(copy.ut_line, "???", sizeof(copy.ut_line)); } // After this, the struct is written to the wtmp file. updwtmp(_PATH_WTMP, ©); }
Variant HHVM_FUNCTION(posix_ttyname, const Variant& fd) { int ttyname_maxlen = sysconf(_SC_TTY_NAME_MAX); if (ttyname_maxlen <= 0) { return false; } String ttyname(ttyname_maxlen, ReserveString); char *p = ttyname.mutableData(); if (ttyname_r(php_posix_get_fd(fd), p, ttyname_maxlen)) { return false; } ttyname.setSize(strlen(p)); return ttyname; }
int isatty(int fd) { libc_func(isatty, int, int); libc_func(readlink, ssize_t, const char*, char*, size_t); int result = _isatty(fd); char ttyname[1024]; char ptymap[PATH_MAX]; char majmin[20]; char *cp; int orig_errno, r; if (result != 1) { DBG(DBG_PATH, "isatty(%i): real function result: %i, returning that\n", fd, result); return result; } /* isatty() succeeds for our emulated devices, but they should not * necessarily appear as TTY; so map the tty name to a major/minor, and * only return 1 if it is major 4. */ orig_errno = errno; if (ttyname_r(fd, ttyname, sizeof(ttyname)) != 0) { DBG(DBG_PATH, "isatty(%i): is a terminal, but ttyname() failed! %m\n", fd); /* *shrug*, what can we do; return original result */ goto out; } DBG(DBG_PATH, "isatty(%i): is a terminal, ttyname %s\n", fd, ttyname); for (cp = ttyname; *cp; ++cp) if (*cp == '/') *cp = '_'; snprintf(ptymap, sizeof(ptymap), "%s/dev/.ptymap/%s", getenv("UMOCKDEV_DIR"), ttyname); r = _readlink(ptymap, majmin, sizeof(majmin)); if (r < 0) { /* failure here is normal for non-emulated devices */ DBG(DBG_PATH, "isatty(%i): readlink(%s) failed: %m\n", fd, ptymap); goto out; } majmin[r] = '\0'; if (majmin[0] != '4' || majmin[1] != ':') { DBG(DBG_PATH, "isatty(%i): major/minor is %s which is not a tty; returning 0\n", fd, majmin); result = 0; } out: errno = orig_errno; return result; }
/* Return the result of ttyname in the buffer pointed to by TTY, which should be of length BUF_LEN. If it is too long to fit in this buffer, a sufficiently long buffer is allocated using malloc, and returned in TTY. 0 is returned upon success, -1 otherwise. */ static int tty_name (int fd, char **tty, size_t buf_len) { int rv; /* Return value. 0 = success. */ char *buf = *tty; /* Buffer for ttyname, initially the user's. */ for (;;) { char *new_buf; if (buf_len) { rv = ttyname_r (fd, buf, buf_len); if (rv != 0 || memchr (buf, '\0', buf_len)) /* We either got an error, or we succeeded and the returned name fit in the buffer. */ break; /* Try again with a longer buffer. */ buf_len += buf_len; /* Double it */ } else /* No initial buffer; start out by mallocing one. */ buf_len = 128; /* First time guess. */ if (buf != *tty) /* We've already malloced another buffer at least once. */ new_buf = realloc (buf, buf_len); else new_buf = malloc (buf_len); if (! new_buf) { rv = -1; __set_errno (ENOMEM); break; } buf = new_buf; } if (rv == 0) *tty = buf; /* Return buffer to the user. */ else if (buf != *tty) free (buf); /* Free what we malloced when returning an error. */ return rv; }
char * ttyname(int fd) { _THREAD_PRIVATE_KEY(ttyname); char * bufp = (char*) _THREAD_PRIVATE(ttyname, buf, NULL); int err; if (bufp == NULL) return NULL; err = ttyname_r(fd, bufp, sizeof buf); if (err) { errno = err; return NULL; } else return bufp; }
static int open_xenconsoled_pty(int *master, int *slave, char *slave_path, size_t slave_path_len) { struct termios termattr; int ret; ret = openpty(master, slave, NULL, NULL, NULL); if (ret < 0) return -1; ret = ttyname_r(*slave, slave_path, slave_path_len); if (ret == -1) { close(*master); close(*slave); *master = *slave = -1; return -1; } /* * On Solaris, the pty master side will get cranky if we try * to write to it while there is no slave. To work around this, * keep the slave descriptor open until we're done. Set it * to raw terminal parameters, otherwise it will echo back * characters, which will confuse the I/O loop below. * Furthermore, a raw master pty device has no terminal * semantics on Solaris, so don't try to set any attributes * for it. */ #if !defined(__sun__) && !defined(__NetBSD__) tcgetattr(*master, &termattr); cfmakeraw(&termattr); tcsetattr(*master, TCSANOW, &termattr); close(*slave); *slave = -1; #else tcgetattr(*slave, &termattr); cfmakeraw(&termattr); tcsetattr(*slave, TCSANOW, &termattr); #endif fcntl(*master, F_SETFL, O_NDELAY); return 0; }
int main(int argc, char** argv) { printf("malloc version...\n"); char* name = ttyname(0); if(name) { printf("name: %s\n", name); }else printf("FAILURE.\n"); printf("Buffer version...\n"); char buff[512]; ttyname_r(0, buff, 512); name = buff; if(name) { printf("name: %s\n", name); }else printf("FAILURE.\n"); return 0; }
int main() { FILE *fp; char buf[1024]; char tty[32]; ttyname_r(fileno(stdin), tty, sizeof(tty)); fp = freopen("./freopen.c", "r", stdin); fgets(buf, sizeof(buf), stdin); printf("%s", buf); printf( "flag 1\n" ); fp = freopen(tty, "r", stdin); fgets(buf, sizeof(buf), stdin); printf("%s", buf); printf( "flag 2\n" ); return 0; }
/* * SNOOPY DATA SOURCE: tty * * Description: * Returns TTY of current process. * * Params: * result: pointer to string, to write result into * arg: (ignored) * * Return: * number of characters in the returned string, or SNOOPY_DATASOURCE_FAILURE */ int snoopy_datasource_tty (char * const result, char const * const arg) { char ttyPath[SNOOPY_DATASOURCE_TTY_sizeMaxWithNull]; size_t ttyPathLen = SNOOPY_DATASOURCE_TTY_sizeMaxWithoutNull; int retVal; retVal = ttyname_r(0, ttyPath, ttyPathLen); if (0 != retVal) { if (EBADF == retVal) { return snprintf(result, SNOOPY_DATASOURCE_MESSAGE_MAX_SIZE, "ERROR(ttyname_r->EBADF)"); } if (ERANGE == retVal) { return snprintf(result, SNOOPY_DATASOURCE_MESSAGE_MAX_SIZE, "ERROR(ttyname_r->ERANGE)"); } if (ENOTTY == retVal) { return snprintf(result, SNOOPY_DATASOURCE_MESSAGE_MAX_SIZE, "(none)"); } return snprintf(result, SNOOPY_DATASOURCE_MESSAGE_MAX_SIZE, "ERROR(ttyname_r->EUNKNOWN)"); } return snprintf(result, SNOOPY_DATASOURCE_MESSAGE_MAX_SIZE, "%s", ttyPath); }