[git commit nptl] libutil/login: was totally broken. fixed

Denys Vlasenko vda.linux at googlemail.com
Tue Apr 6 15:17:30 UTC 2010


commit: http://git.uclibc.org/uClibc/commit/?id=b2f0faf04264c13d7877646330da7f5954380342
branch: http://git.uclibc.org/uClibc/commit/?id=refs/heads/nptl

Also made login() and logout() usable with utmpname(non_std_utmp_file)
   text           data     bss     dec     hex filename
    111              0       0     111      6f libutil/login.o
    217              0       0     217      d9 libutil/login.o
   text           data     bss     dec     hex filename
    164              0       0     164      a4 libutil/logout.o
    134              0       0     134      86 libutil/logout.o

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 libutil/login.c  |   57 +++++++++++++++++++++++++++++++++++++++++++----------
 libutil/logout.c |   20 +++++++++---------
 2 files changed, 56 insertions(+), 21 deletions(-)

diff --git a/libutil/login.c b/libutil/login.c
index bd1dd29..4007e4c 100644
--- a/libutil/login.c
+++ b/libutil/login.c
@@ -5,21 +5,56 @@
 #include <stdlib.h>
 #include <utmp.h>
 
-/* Write the given entry into utmp and wtmp.  */
-void login (const struct utmp *entry)
+/* 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 = *entry;
+	struct utmp copy;
+	char tty_name[sizeof(copy.ut_line) + 6];
+	int fd;
 
-    utmpname(_PATH_UTMP);
-    setutent();
+// 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;
+	copy.ut_type = USER_PROCESS;
 #endif
 #if _HAVE_UT_PID - 0
-    copy.ut_pid = getpid();
+	copy.ut_pid = getpid();
 #endif
-    strncpy (copy.ut_line, entry->ut_line, UT_LINESIZE);
-    pututline(entry);
-    endutent();
-}
 
+// 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(&copy);
+		endutent();
+	} else {
+		strncpy(copy.ut_line, "???", sizeof(copy.ut_line));
+	}
+
+// After this, the struct is written to the wtmp file.
+	updwtmp(_PATH_WTMP, &copy);
+}
diff --git a/libutil/logout.c b/libutil/logout.c
index e6d9565..5f58b8f 100644
--- a/libutil/logout.c
+++ b/libutil/logout.c
@@ -29,9 +29,9 @@ logout (const char *line)
   struct utmp *ut;
   int result = 0;
 
-  /* Tell that we want to use the UTMP file.  */
-  if (utmpname (_PATH_UTMP) == -1)
-    return 0;
+  /* if (utmpname (_PATH_UTMP) == -1) return 0; - why?
+   * this makes it impossible for caller to use other file!
+   * Does any standard or historical precedent says this must be done? */
 
   /* Open UTMP file.  */
   setutent ();
@@ -43,7 +43,7 @@ logout (const char *line)
   strncpy (tmp.ut_line, line, sizeof tmp.ut_line);
 
   /* Read the record.  */
-  if( (ut =  getutline(&tmp)) )
+  if ((ut = getutline(&tmp)) != NULL)
     {
       /* Clear information about who & from where.  */
       memset (ut->ut_name, 0, sizeof ut->ut_name);
@@ -54,12 +54,12 @@ logout (const char *line)
 # if !defined __WORDSIZE_COMPAT32 || __WORDSIZE_COMPAT32 == 0
       gettimeofday (&ut->ut_tv, NULL);
 # else
-    {
-      struct timeval tv;
-      gettimeofday (&tv, NULL);
-      ut->ut_tv.tv_sec = tv.tv_sec;
-      ut->ut_tv.tv_usec = tv.tv_usec;
-    }
+      {
+	struct timeval tv;
+	gettimeofday (&tv, NULL);
+	ut->ut_tv.tv_sec = tv.tv_sec;
+	ut->ut_tv.tv_usec = tv.tv_usec;
+      }
 # endif
 #else
       time (&ut->ut_time);
-- 
1.6.3.3



More information about the uClibc-cvs mailing list