X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/d6fa1947ccca4a61baf25d22d6455e9acbf8d422..5fb0e72d2051c29599c07c54af02960fa2e21fcb:/unix/uxpty.c diff --git a/unix/uxpty.c b/unix/uxpty.c index 8a3dbe6f..c3174373 100644 --- a/unix/uxpty.c +++ b/unix/uxpty.c @@ -2,8 +2,6 @@ * Pseudo-tty backend for pterm. */ -#define _XOPEN_SOURCE 600 -#define _XOPEN_SOURCE_EXTENDED #define _GNU_SOURCE #include @@ -26,6 +24,10 @@ #include "putty.h" #include "tree234.h" +#ifndef OMIT_UTMP +#include +#endif + #ifndef FALSE #define FALSE 0 #endif @@ -33,12 +35,15 @@ #define TRUE 1 #endif -#ifndef UTMP_FILE -#define UTMP_FILE "/var/run/utmp" +/* updwtmpx() needs the name of the wtmp file. Try to find it. */ +#ifndef WTMPX_FILE +#ifdef _PATH_WTMPX +#define WTMPX_FILE _PATH_WTMPX +#else +#define WTMPX_FILE "/var/log/wtmpx" #endif -#ifndef WTMP_FILE -#define WTMP_FILE "/var/log/wtmp" #endif + #ifndef LASTLOG_FILE #ifdef _PATH_LASTLOG #define LASTLOG_FILE _PATH_LASTLOG @@ -162,7 +167,7 @@ static Pty single_pty = NULL; #ifndef OMIT_UTMP static int pty_utmp_helper_pid, pty_utmp_helper_pipe; static int pty_stamped_utmp; -static struct utmp utmp_entry; +static struct utmpx utmp_entry; #endif /* @@ -171,7 +176,6 @@ static struct utmp utmp_entry; * make sense outside a one-pty-per-process setup. */ char **pty_argv; -int use_pty_argv; static void pty_close(Pty pty); @@ -183,8 +187,7 @@ static void setup_utmp(char *ttyname, char *location) FILE *lastlog; #endif struct passwd *pw; - FILE *wtmp; - time_t uttime; + struct timeval tv; pw = getpwuid(getuid()); memset(&utmp_entry, 0, sizeof(utmp_entry)); @@ -194,22 +197,20 @@ static void setup_utmp(char *ttyname, char *location) strncpy(utmp_entry.ut_id, ttyname+8, lenof(utmp_entry.ut_id)); strncpy(utmp_entry.ut_user, pw->pw_name, lenof(utmp_entry.ut_user)); strncpy(utmp_entry.ut_host, location, lenof(utmp_entry.ut_host)); - /* Apparently there are some architectures where (struct utmp).ut_time - * is not essentially time_t (e.g. Linux amd64). Hence the temporary. */ - time(&uttime); - utmp_entry.ut_time = uttime; /* may truncate */ - -#if defined HAVE_PUTUTLINE - utmpname(UTMP_FILE); - setutent(); - pututline(&utmp_entry); - endutent(); -#endif + /* + * Apparently there are some architectures where (struct + * utmpx).ut_tv is not essentially struct timeval (e.g. Linux + * amd64). Hence the temporary. + */ + gettimeofday(&tv, NULL); + utmp_entry.ut_tv.tv_sec = tv.tv_sec; + utmp_entry.ut_tv.tv_usec = tv.tv_usec; - if ((wtmp = fopen(WTMP_FILE, "a")) != NULL) { - fwrite(&utmp_entry, 1, sizeof(utmp_entry), wtmp); - fclose(wtmp); - } + setutxent(); + pututxline(&utmp_entry); + endutxent(); + + updwtmpx(WTMPX_FILE, &utmp_entry); #ifdef HAVE_LASTLOG memset(&lastlog_entry, 0, sizeof(lastlog_entry)); @@ -229,31 +230,26 @@ static void setup_utmp(char *ttyname, char *location) static void cleanup_utmp(void) { - FILE *wtmp; - time_t uttime; + struct timeval tv; if (!pty_stamped_utmp) return; utmp_entry.ut_type = DEAD_PROCESS; memset(utmp_entry.ut_user, 0, lenof(utmp_entry.ut_user)); - time(&uttime); - utmp_entry.ut_time = uttime; + gettimeofday(&tv, NULL); + utmp_entry.ut_tv.tv_sec = tv.tv_sec; + utmp_entry.ut_tv.tv_usec = tv.tv_usec; - if ((wtmp = fopen(WTMP_FILE, "a")) != NULL) { - fwrite(&utmp_entry, 1, sizeof(utmp_entry), wtmp); - fclose(wtmp); - } + updwtmpx(WTMPX_FILE, &utmp_entry); memset(utmp_entry.ut_line, 0, lenof(utmp_entry.ut_line)); - utmp_entry.ut_time = 0; + utmp_entry.ut_tv.tv_sec = 0; + utmp_entry.ut_tv.tv_usec = 0; -#if defined HAVE_PUTUTLINE - utmpname(UTMP_FILE); - setutent(); - pututline(&utmp_entry); - endutent(); -#endif + setutxent(); + pututxline(&utmp_entry); + endutxent(); pty_stamped_utmp = 0; /* ensure we never double-cleanup */ } @@ -748,7 +744,9 @@ static const char *pty_init(void *frontend, void **backend_handle, Config *cfg, dup2(slavefd, 1); dup2(slavefd, 2); setsid(); +#ifdef TIOCSCTTY ioctl(slavefd, TIOCSCTTY, 1); +#endif pgrp = getpid(); tcsetpgrp(slavefd, pgrp); setpgid(pgrp, pgrp); @@ -758,15 +756,19 @@ static const char *pty_init(void *frontend, void **backend_handle, Config *cfg, for (i = 3; i < 1024; i++) close(i); { - char term_env_var[10 + sizeof(cfg->termtype)]; - sprintf(term_env_var, "TERM=%s", cfg->termtype); + char *term_env_var = dupprintf("TERM=%s", cfg->termtype); putenv(term_env_var); + /* We mustn't free term_env_var, as putenv links it into the + * environment in place. + */ } #ifndef NOT_X_WINDOWS /* for Mac OS X native compilation */ { - char windowid_env_var[40]; - sprintf(windowid_env_var, "WINDOWID=%ld", windowid); + char *windowid_env_var = dupprintf("WINDOWID=%ld", windowid); putenv(windowid_env_var); + /* We mustn't free windowid_env_var, as putenv links it into the + * environment in place. + */ } #endif { @@ -814,7 +816,7 @@ static const char *pty_init(void *frontend, void **backend_handle, Config *cfg, sprintf(shellname, "-%s", p); } else shellname = shell; - execl(getenv("SHELL"), shellname, NULL); + execl(getenv("SHELL"), shellname, (void *)NULL); } /*