diff options
-rw-r--r-- | include/utmp.h | 1 | ||||
-rw-r--r-- | libc/inet/resolv.c | 4 | ||||
-rw-r--r-- | libc/misc/fnmatch/fnmatch.c | 8 | ||||
-rw-r--r-- | libc/misc/regex/regex_old.c | 6 | ||||
-rw-r--r-- | libc/misc/utmp/utent.c | 91 | ||||
-rw-r--r-- | libc/sysdeps/linux/i386/bits/syscalls.h | 263 | ||||
-rw-r--r-- | libc/unistd/confstr.c | 18 | ||||
-rw-r--r-- | libutil/login.c | 57 | ||||
-rw-r--r-- | libutil/logout.c | 20 | ||||
-rw-r--r-- | test/Rules.mak | 1 | ||||
-rw-r--r-- | test/unistd/Makefile.in | 7 | ||||
-rw-r--r-- | utils/Makefile.in | 7 | ||||
-rw-r--r-- | utils/getconf.c (renamed from test/unistd/getconf.c) | 0 |
13 files changed, 297 insertions, 186 deletions
diff --git a/include/utmp.h b/include/utmp.h index 182f45e1c..27454a66a 100644 --- a/include/utmp.h +++ b/include/utmp.h @@ -74,7 +74,6 @@ extern void endutent (void) __THROW; /* Search forward from the current point in the utmp file until the next entry with a ut_type matching ID->ut_type. */ extern struct utmp *getutid (__const struct utmp *__id) __THROW; -libc_hidden_proto(getutid) /* Search forward from the current point in the utmp file until the next entry with a ut_line matching LINE->ut_line. */ diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index 056539f6e..9459199da 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -1517,10 +1517,8 @@ int attribute_hidden __dns_lookup(const char *name, memcpy(a, &ma, sizeof(ma)); if (a->atype != T_SIG && (NULL == a->buf || (type != T_A && type != T_AAAA))) break; - if (a->atype != type) { - free(a->dotted); + if (a->atype != type) continue; - } a->add_count = h.ancount - j - 1; if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen) break; diff --git a/libc/misc/fnmatch/fnmatch.c b/libc/misc/fnmatch/fnmatch.c index d25619b34..0fa043bad 100644 --- a/libc/misc/fnmatch/fnmatch.c +++ b/libc/misc/fnmatch/fnmatch.c @@ -21,13 +21,7 @@ # include <config.h> #endif -/* include unistd.h before we undefine _LIBC - * because smallint is defined in unistd.h based - * on _LIBC. For architectures that dont define - * smallint of there own and rely upon the definition - * from unistd.h will not build this file otherwise - */ - +/* unistd.h must be included with _LIBC defined: we need smallint */ #include <unistd.h> #include <features.h> #ifdef __UCLIBC__ diff --git a/libc/misc/regex/regex_old.c b/libc/misc/regex/regex_old.c index bc2ad6cb8..a3c30b51a 100644 --- a/libc/misc/regex/regex_old.c +++ b/libc/misc/regex/regex_old.c @@ -23,7 +23,8 @@ /* To exclude some unwanted junk.... */ #undef emacs #include <features.h> - +/* unistd.h must be included with _LIBC defined: we need smallint */ +#include <unistd.h> #ifdef __UCLIBC__ # undef _LIBC # define _REGEX_RE_COMP @@ -33,7 +34,6 @@ #include <stdlib.h> #include <stdint.h> #include <string.h> -#include <unistd.h> #include <stdio.h> /* AIX requires this to be the first thing in the file. */ @@ -263,7 +263,7 @@ static void init_syntax_once (void) { register int c; - static int done = 0; + static smallint done = 0; if (done) return; diff --git a/libc/misc/utmp/utent.c b/libc/misc/utmp/utent.c index a3f01b6e9..a678130a3 100644 --- a/libc/misc/utmp/utent.c +++ b/libc/misc/utmp/utent.c @@ -25,14 +25,26 @@ __UCLIBC_MUTEX_STATIC(utmplock, PTHREAD_MUTEX_INITIALIZER); +/* Do not create extra unlocked functions if no locking is needed */ +#if defined __UCLIBC_HAS_THREADS__ +# define static_if_threaded static +#else +# define static_if_threaded /* nothing */ +# define __setutent setutent +# define __getutent getutent +# define __getutid getutid +#endif + + /* Some global crap */ static int static_fd = -1; static struct utmp static_utmp; static const char default_file_name[] = _PATH_UTMP; static const char *static_ut_name = default_file_name; + /* This function must be called with the LOCK held */ -static void __setutent(void) +static_if_threaded void __setutent(void) { if (static_fd < 0) { static_fd = open_not_cancel_2(static_ut_name, O_RDWR | O_CLOEXEC); @@ -50,20 +62,19 @@ static void __setutent(void) } lseek(static_fd, 0, SEEK_SET); } - +#if defined __UCLIBC_HAS_THREADS__ void setutent(void) { __UCLIBC_MUTEX_LOCK(utmplock); __setutent(); __UCLIBC_MUTEX_UNLOCK(utmplock); } +#endif libc_hidden_def(setutent) /* This function must be called with the LOCK held */ -static struct utmp *__getutent(void) +static_if_threaded struct utmp *__getutent(void) { - struct utmp *ret = NULL; - if (static_fd < 0) { __setutent(); if (static_fd < 0) { @@ -72,11 +83,22 @@ static struct utmp *__getutent(void) } if (read_not_cancel(static_fd, &static_utmp, sizeof(static_utmp)) == sizeof(static_utmp)) { - ret = &static_utmp; + return &static_utmp; } + return NULL; +} +#if defined __UCLIBC_HAS_THREADS__ +struct utmp *getutent(void) +{ + struct utmp *ret; + + __UCLIBC_MUTEX_LOCK(utmplock); + ret = __getutent(); + __UCLIBC_MUTEX_UNLOCK(utmplock); return ret; } +#endif void endutent(void) { @@ -87,63 +109,52 @@ void endutent(void) __UCLIBC_MUTEX_UNLOCK(utmplock); } -struct utmp *getutent(void) -{ - struct utmp *ret = NULL; - - __UCLIBC_MUTEX_LOCK(utmplock); - ret = __getutent(); - __UCLIBC_MUTEX_UNLOCK(utmplock); - return ret; -} - /* This function must be called with the LOCK held */ -static struct utmp *__getutid(const struct utmp *utmp_entry) +static_if_threaded struct utmp *__getutid(const struct utmp *utmp_entry) { struct utmp *lutmp; + unsigned type; + + /* We use the fact that constants we are interested in are: */ + /* RUN_LVL=1, ... OLD_TIME=4; INIT_PROCESS=5, ... USER_PROCESS=8 */ + type = utmp_entry->ut_type - 1; + type /= 4; while ((lutmp = __getutent()) != NULL) { - if ( (utmp_entry->ut_type == RUN_LVL || - utmp_entry->ut_type == BOOT_TIME || - utmp_entry->ut_type == NEW_TIME || - utmp_entry->ut_type == OLD_TIME) && - lutmp->ut_type == utmp_entry->ut_type) - { - return lutmp; - } - if ( (utmp_entry->ut_type == INIT_PROCESS || - utmp_entry->ut_type == DEAD_PROCESS || - utmp_entry->ut_type == LOGIN_PROCESS || - utmp_entry->ut_type == USER_PROCESS) && - !strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id))) - { - return lutmp; - } + if (type == 0 && lutmp->ut_type == utmp_entry->ut_type) { + /* one of RUN_LVL, BOOT_TIME, NEW_TIME, OLD_TIME */ + return lutmp; + } + if (type == 1 && strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id)) == 0) { + /* INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, DEAD_PROCESS */ + return lutmp; + } } return NULL; } - +#if defined __UCLIBC_HAS_THREADS__ struct utmp *getutid(const struct utmp *utmp_entry) { - struct utmp *ret = NULL; + struct utmp *ret; __UCLIBC_MUTEX_LOCK(utmplock); ret = __getutid(utmp_entry); __UCLIBC_MUTEX_UNLOCK(utmplock); return ret; } -libc_hidden_def(getutid) +#endif struct utmp *getutline(const struct utmp *utmp_entry) { - struct utmp *lutmp = NULL; + struct utmp *lutmp; __UCLIBC_MUTEX_LOCK(utmplock); while ((lutmp = __getutent()) != NULL) { - if ((lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) && - !strcmp(lutmp->ut_line, utmp_entry->ut_line)) { - break; + if (lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) { + if (strncmp(lutmp->ut_line, utmp_entry->ut_line, sizeof(lutmp->ut_line)) == 0) { + break; + } } } __UCLIBC_MUTEX_UNLOCK(utmplock); diff --git a/libc/sysdeps/linux/i386/bits/syscalls.h b/libc/sysdeps/linux/i386/bits/syscalls.h index f9ea54ac7..0427d91cd 100644 --- a/libc/sysdeps/linux/i386/bits/syscalls.h +++ b/libc/sysdeps/linux/i386/bits/syscalls.h @@ -1,142 +1,189 @@ #ifndef _BITS_SYSCALLS_H #define _BITS_SYSCALLS_H + #ifndef _SYSCALL_H # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead." #endif /* - Some of the sneaky macros in the code were taken from - glibc-2.2.5/sysdeps/unix/sysv/linux/i386/sysdep.h -*/ + * Some of the sneaky macros in the code were taken from + * glibc-2.2.5/sysdeps/unix/sysv/linux/i386/sysdep.h + */ #ifndef __ASSEMBLER__ #include <errno.h> -/* We need some help from the assembler to generate optimal code. We - define some macros here which later will be used. */ +#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ +({ \ + register unsigned int resultvar; \ + __asm__ __volatile__ ( \ + LOADARGS_##nr \ + "movl %1, %%eax\n\t" \ + "int $0x80\n\t" \ + RESTOREARGS_##nr \ + : "=a" (resultvar) \ + : "i" (name) ASMFMT_##nr(args) : "memory", "cc" \ + ); \ + (int) resultvar; \ +}) + -#if defined __SUPPORT_LD_DEBUG__ && defined __DOMULTI__ -#error LD debugging and DOMULTI are incompatible -#endif +#if 1 /* defined __PIC__ || defined __pic__ */ +/* This code avoids pushing/popping ebx as much as possible. + * I think the main reason was that older GCCs had problems + * with proper saving/restoring of ebx if "b" constraint was used, + * which was breaking -fPIC code really badly. + * At least gcc 4.2.x seems to not need these tricks anymore, + * but this code is still useful because it often avoids + * using stack for saving ebx. + * Keeping it unconditionally enabled for now. + */ + +/* We need some help from the assembler to generate optimal code. + * We define some macros here which later will be used. */ + +__asm__ ( #ifdef __DOMULTI__ -__asm__ (".L__X'%ebx = 1\n\t" - ".L__X'%ecx = 2\n\t" - ".L__X'%edx = 2\n\t" - ".L__X'%eax = 3\n\t" - ".L__X'%esi = 3\n\t" - ".L__X'%edi = 3\n\t" - ".L__X'%ebp = 3\n\t" - ".L__X'%esp = 3\n\t" - ".ifndef _BITS_SYSCALLS_ASM\n\t" - ".set _BITS_SYSCALLS_ASM,1\n\t" - ".macro bpushl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "pushl %ebx\n\t" - ".else\n\t" - "xchgl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t" - ".macro bpopl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "popl %ebx\n\t" - ".else\n\t" - "xchgl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t" - ".macro bmovl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "movl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t" - ".endif\n\t"); -#else -__asm__ (".L__X'%ebx = 1\n\t" - ".L__X'%ecx = 2\n\t" - ".L__X'%edx = 2\n\t" - ".L__X'%eax = 3\n\t" - ".L__X'%esi = 3\n\t" - ".L__X'%edi = 3\n\t" - ".L__X'%ebp = 3\n\t" - ".L__X'%esp = 3\n\t" - ".macro bpushl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "pushl %ebx\n\t" - ".else\n\t" - "xchgl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t" - ".macro bpopl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "popl %ebx\n\t" - ".else\n\t" - "xchgl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t" - ".macro bmovl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "movl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t"); + /* Protect against asm macro redefinition (happens in __DOMULTI__ mode). + * Unfortunately, it ends up visible in .o files. */ + ".ifndef _BITS_SYSCALLS_ASM\n\t" + ".set _BITS_SYSCALLS_ASM,1\n\t" #endif + ".L__X'%ebx = 1\n\t" + ".L__X'%ecx = 2\n\t" + ".L__X'%edx = 2\n\t" + ".L__X'%eax = 3\n\t" + ".L__X'%esi = 3\n\t" + ".L__X'%edi = 3\n\t" + ".L__X'%ebp = 3\n\t" + ".L__X'%esp = 3\n\t" -#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ - ({ \ - register unsigned int resultvar; \ - __asm__ __volatile__ ( \ - LOADARGS_##nr \ - "movl %1, %%eax\n\t" \ - "int $0x80\n\t" \ - RESTOREARGS_##nr \ - : "=a" (resultvar) \ - : "g" (name) ASMFMT_##nr(args) : "memory", "cc"); \ - (int) resultvar; }) + /* Loading param #1 (ebx) is done by loading it into + * another register, and then performing bpushl+bmovl, + * since we must preserve ebx */ + + ".macro bpushl name reg\n\t" + ".if 1 - \\name\n\t" /* if reg!=ebx... */ + ".if 2 - \\name\n\t" /* if reg can't be clobbered... */ + "pushl %ebx\n\t" /* save ebx on stack */ + ".else\n\t" + "xchgl \\reg, %ebx\n\t" /* else save ebx in reg, and load reg to ebx */ + ".endif\n\t" + ".endif\n\t" + ".endm\n\t" + + ".macro bmovl name reg\n\t" + ".if 1 - \\name\n\t" + ".if 2 - \\name\n\t" /* if reg can't be clobbered... */ + "movl \\reg, %ebx\n\t" /* load reg to ebx */ + ".endif\n\t" + ".endif\n\t" + ".endm\n\t" + + ".macro bpopl name reg\n\t" + ".if 1 - \\name\n\t" + ".if 2 - \\name\n\t" /* if reg can't be clobbered... */ + "popl %ebx\n\t" /* restore ebx from stack */ + ".else\n\t" + "xchgl \\reg, %ebx\n\t" /* else restore ebx from reg */ + ".endif\n\t" + ".endif\n\t" + ".endm\n\t" + +#ifdef __DOMULTI__ + ".endif\n\t" /* _BITS_SYSCALLS_ASM */ +#endif +); #define LOADARGS_0 -#define LOADARGS_1 \ - "bpushl .L__X'%k2, %k2\n\t" \ - "bmovl .L__X'%k2, %k2\n\t" -#define LOADARGS_2 LOADARGS_1 -#define LOADARGS_3 LOADARGS_1 -#define LOADARGS_4 LOADARGS_1 -#define LOADARGS_5 LOADARGS_1 -#define LOADARGS_6 LOADARGS_1 "push %%ebp ; movl %7, %%ebp\n\t" +#define LOADARGS_1 "bpushl .L__X'%k2, %k2\n\t" "bmovl .L__X'%k2, %k2\n\t" +#define LOADARGS_2 LOADARGS_1 +#define LOADARGS_3 LOADARGS_1 +#define LOADARGS_4 LOADARGS_1 +#define LOADARGS_5 LOADARGS_1 +#define LOADARGS_6 LOADARGS_1 "push %%ebp\n\t" "movl %7, %%ebp\n\t" #define RESTOREARGS_0 -#define RESTOREARGS_1 \ - "bpopl .L__X'%k2, %k2\n\t" -#define RESTOREARGS_2 RESTOREARGS_1 -#define RESTOREARGS_3 RESTOREARGS_1 -#define RESTOREARGS_4 RESTOREARGS_1 -#define RESTOREARGS_5 RESTOREARGS_1 -#define RESTOREARGS_6 "pop %%ebp\n\t" RESTOREARGS_1 +#define RESTOREARGS_1 "bpopl .L__X'%k2, %k2\n\t" +#define RESTOREARGS_2 RESTOREARGS_1 +#define RESTOREARGS_3 RESTOREARGS_1 +#define RESTOREARGS_4 RESTOREARGS_1 +#define RESTOREARGS_5 RESTOREARGS_1 +#define RESTOREARGS_6 "pop %%ebp\n\t" RESTOREARGS_1 #define ASMFMT_0() +/* "acdSD" constraint would work too, but "SD" would use esi/edi and cause + * them to be pushed/popped by compiler, "a" would use eax and cause ebx + * to be saved/restored on stack, not in register. Narrowing choice down + * to "ecx or edx" results in smaller and faster code: */ #define ASMFMT_1(arg1) \ - , "acdSD" (arg1) + , "cd" (arg1) +/* Can use "adSD" constraint here: */ #define ASMFMT_2(arg1, arg2) \ - , "adSD" (arg1), "c" (arg2) + , "d" (arg1), "c" (arg2) +/* Can use "aSD" constraint here: */ #define ASMFMT_3(arg1, arg2, arg3) \ - , "aSD" (arg1), "c" (arg2), "d" (arg3) + , "a" (arg1), "c" (arg2), "d" (arg3) +/* Can use "aD" constraint here: */ #define ASMFMT_4(arg1, arg2, arg3, arg4) \ - , "aD" (arg1), "c" (arg2), "d" (arg3), "S" (arg4) + , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4) #define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \ , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5) #define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \ , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "m" (arg6) +#else /* !PIC */ + +/* Simpler code which just uses "b" constraint to load ebx. + * Seems to work with gc 4.2.x, and generates slightly smaller, + * but slightly slower code. Example (time syscall): + * + * - 8b 4c 24 04 mov 0x4(%esp),%ecx + * - 87 cb xchg %ecx,%ebx + * + 53 push %ebx + * + 8b 5c 24 08 mov 0x8(%esp),%ebx + * b8 0d 00 00 00 mov $0xd,%eax + * cd 80 int $0x80 + * - 87 cb xchg %ecx,%ebx + * + 5b pop %ebx + * c3 ret + * + * 2 bytes smaller, but uses stack via "push/pop ebx" + */ + +#define LOADARGS_0 +#define LOADARGS_1 +#define LOADARGS_2 +#define LOADARGS_3 +#define LOADARGS_4 +#define LOADARGS_5 +#define LOADARGS_6 "push %%ebp\n\t" "movl %7, %%ebp\n\t" + +#define RESTOREARGS_0 +#define RESTOREARGS_1 +#define RESTOREARGS_2 +#define RESTOREARGS_3 +#define RESTOREARGS_4 +#define RESTOREARGS_5 +#define RESTOREARGS_6 "pop %%ebp\n\t" + +#define ASMFMT_0() +#define ASMFMT_1(arg1) \ + , "b" (arg1) +#define ASMFMT_2(arg1, arg2) \ + , "b" (arg1), "c" (arg2) +#define ASMFMT_3(arg1, arg2, arg3) \ + , "b" (arg1), "c" (arg2), "d" (arg3) +#define ASMFMT_4(arg1, arg2, arg3, arg4) \ + , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4) +#define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \ + , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5) +#define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \ + , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "m" (arg6) + +#endif /* !PIC */ + #endif /* __ASSEMBLER__ */ #endif /* _BITS_SYSCALLS_H */ diff --git a/libc/unistd/confstr.c b/libc/unistd/confstr.c index 16b57bee9..957ee4d27 100644 --- a/libc/unistd/confstr.c +++ b/libc/unistd/confstr.c @@ -42,6 +42,24 @@ size_t confstr (int name, char *buf, size_t len) string_len = sizeof (cs_path); } break; +#ifdef __UCLIBC_HAS_THREADS__ + case _CS_GNU_LIBPTHREAD_VERSION: +# if defined __LINUXTHREADS_OLD__ + string = "linuxthreads-0.01"; + string_len = sizeof("linuxthreads-x.xx"); +# elif defined __LINUXTHREADS_NEW__ + string = "linuxthreads-0.10"; + string_len = sizeof("linuxthreads-x.xx"); +# elif defined __UCLIBC_HAS_THREADS_NATIVE__ +# define __NPTL_VERSION ("NPTL " \ + #__UCLIBC_MAJOR__ "." \ + #__UCLIBC_MINOR__ "." \ + #__UCLIBC_SUBLEVEL__) + string = __NPTL_VERSION; + string_len = sizeof(__NPTL_VERSION); +# endif + break; +#endif default: __set_errno (EINVAL); return 0; diff --git a/libutil/login.c b/libutil/login.c index bd1dd29ee..4007e4c7e 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(©); + endutent(); + } else { + strncpy(copy.ut_line, "???", sizeof(copy.ut_line)); + } + +// After this, the struct is written to the wtmp file. + updwtmp(_PATH_WTMP, ©); +} diff --git a/libutil/logout.c b/libutil/logout.c index e6d9565ab..5f58b8f42 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); diff --git a/test/Rules.mak b/test/Rules.mak index 29b551fa1..2131a7b18 100644 --- a/test/Rules.mak +++ b/test/Rules.mak @@ -44,6 +44,7 @@ endif export TARGET_ARCH RM_R = $(Q)$(RM) -r +LN_S = $(Q)$(LN) -fs ifneq ($(KERNEL_HEADERS),) ifeq ($(patsubst /%,/,$(KERNEL_HEADERS)),/) diff --git a/test/unistd/Makefile.in b/test/unistd/Makefile.in index ae0eeb499..8ddfc52da 100644 --- a/test/unistd/Makefile.in +++ b/test/unistd/Makefile.in @@ -10,6 +10,11 @@ else OPTS_tstgetopt := -a -b -cfoobar --required foobar --optional=bazbug --none --colou --color --colour random endif -TESTS_DISABLED+=getconf +# getconf.c lives in utils/ +# Testsuite cannot currently be built with O= anyway, so hardcode path here +getconf.c: + $(LN_S) ../../utils/$(@F) . +EXTRA_CLEAN += getconf.c +TESTS_DISABLED += getconf CFLAGS_getconf = -DGETCONF_DIR='"$(CURDIR)"' shell_tst-getconf: getconf getconf_glibc diff --git a/utils/Makefile.in b/utils/Makefile.in index 2aae1df71..89cb800e9 100644 --- a/utils/Makefile.in +++ b/utils/Makefile.in @@ -40,7 +40,8 @@ CFLAGS-iconv := $(CFLAGS-utils) \ -DL_iconv_main \ CFLAGS-locale := $(CFLAGS-utils) - +CFLAGS-getconf :=$(CFLAGS-utils) \ + -DGETCONF_DIR='"$(CURDIR)"' # "make hostutils" flags @@ -76,6 +77,7 @@ utils_OUT := $(top_builddir)utils DEPS-ldconfig := $(utils_DIR)/chroot_realpath.c DEPS-ldconfig.host := $(DEPS-ldconfig) +utils_OBJ := getconf ifeq ($(HAVE_SHARED),y) utils_OBJ += ldconfig ldd endif @@ -115,6 +117,7 @@ install-y += utils_install # This installs both utils and hostutils, so doesn't depend on either. utils_install: $(addsuffix $(DOTHOST), $(utils_OBJ) $(utils_LOCALE_OBJ)) + $(Q)$(INSTALL) -D -m 755 $(utils_OUT)/getconf$(DOTHOST) $(PREFIX)$(DEVEL_PREFIX)usr/bin/getconf ifeq ($(HAVE_SHARED),y) $(Q)$(INSTALL) -D -m 755 $(utils_OUT)/ldd$(DOTHOST) $(PREFIX)$(DEVEL_PREFIX)bin/ldd $(Q)$(INSTALL) -D -m 755 $(utils_OUT)/ldconfig$(DOTHOST) $(PREFIX)$(RUNTIME_PREFIX)sbin/ldconfig @@ -128,6 +131,6 @@ endif objclean-y += CLEAN_utils CLEAN_utils: - $(do_rm) $(addprefix $(utils_OUT)/, ldconfig ldd iconv locale *.host) + $(do_rm) $(addprefix $(utils_OUT)/, getconf iconv ldconfig ldd locale *.host) $(Q)# This is a hack.. $(Q)$(RM) $(utils_OUT)/.*.dep diff --git a/test/unistd/getconf.c b/utils/getconf.c index 81566df7b..81566df7b 100644 --- a/test/unistd/getconf.c +++ b/utils/getconf.c |