mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 17:53:37 +08:00
Tue May 28 04:38:10 1996 Ulrich Drepper <drepper@cygnus.com>
* limits.h: Change MB_LEN_MAX to 6. A 31-bit ISO 10646 character in UTF-8 encoding has that many bytes. * locale/langinfo.h: New element _NL_CTYPE_MB_CUR_MAX. * locale/categories.def: Add description of field _NL_CTYPE_MB_CUR_MAX. * locale/Makefile (routines): Add mb_cur_max. * locale/mb_cur_max.c: New file. This function gets called when the macro MB_CUR_MAX is used. * locale/C-ctype.c: Initialize new mb_cur_max field. * locale/localeinfo.h: Change magic value because of incompatible change. * locale/programs/ld-ctype.c: Determine value of mb_cur_max according to current character set and write it out with the rest. * stdlib/stdlib.h (MB_CUR_MAX): Not constant anymore. Get value according to currently used locale for catefory LC_CTYPE by calling the function __ctype_get_mb_cur_max. Tue May 28 03:27:46 1996 Ulrich Drepper <drepper@cygnus.com> * FAQ: Fix some typos. Tell that for Linux the kernel header files are necessary. * PROJECTS: New file. List of open jobs for glibc. * Makefile (distribute): Add PROJECTS. * crypt/GNUmakefile (headers): New variable. Mention crypt.h. * crypt/crypt.h: Header for crypt functions. * elf/elf.h: Add some new constants from recent Cygnus ELF header files. * login/getutid_r.c: Test for correct type. Don't depend on ut_type and ut_id unless _HAVE_UT_TYPE and _HAVE_UT_ID resp. are defined. Make really compliant with specification. * login/getutline_r.c, login/pututline_r.c: Don't depend on ut_type and ut_id unless _HAVE_UT_TYPE and _HAVE_UT_ID resp. are defined. Make really compliant with specification. * login/setutent_r.c: Don't depend on ut_type and ut_id unless _HAVE_UT_TYPE and _HAVE_UT_ID resp. are defined. * login/login.c, login/logout.c, login/logwtmp.c: Complete rewrite. Now based on getut*/setut* functions. * stdlib/strtol.c: Undo changes of Wed May 22 01:48:54 1996. This prevented using this file in other GNU packages. * sysdeps/gnu/utmpbits.h: Define _HAVE_UT_TYPE, _HAVE_UT_ID, and _HAVE_UT_TV because struct utmp has these members. * sysdeps/libm-i387/e_exp.S: Correct exp(+-Inf) case. * utmp.h: New file. Wrapper around login/utmp.h. * elf/dl-error.c (struct catch): New type. (catch): New static variable, struct catch *. (catch_env, signalled_errstring, signalled_objname): Variables removed. (_dl_signal_error): If CATCH is non-null, set its errstring and objname members and jump to CATCH->env. If it is null, call _dl_sysdep_fatal with a standard message. * elf/rtld.c (dl_main): Explode `doit' function into dl_main's body. No longer use _dl_catch_error.
This commit is contained in:
parent
215dbbb150
commit
0200214b28
68
ChangeLog
68
ChangeLog
@ -1,5 +1,73 @@
|
||||
Tue May 28 04:38:10 1996 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* limits.h: Change MB_LEN_MAX to 6. A 31-bit ISO 10646
|
||||
character in UTF-8 encoding has that many bytes.
|
||||
|
||||
* locale/langinfo.h: New element _NL_CTYPE_MB_CUR_MAX.
|
||||
* locale/categories.def: Add description of field _NL_CTYPE_MB_CUR_MAX.
|
||||
* locale/Makefile (routines): Add mb_cur_max.
|
||||
* locale/mb_cur_max.c: New file. This function gets called
|
||||
when the macro MB_CUR_MAX is used.
|
||||
* locale/C-ctype.c: Initialize new mb_cur_max field.
|
||||
* locale/localeinfo.h: Change magic value because of incompatible
|
||||
change.
|
||||
* locale/programs/ld-ctype.c: Determine value of mb_cur_max
|
||||
according to current character set and write it out with the rest.
|
||||
* stdlib/stdlib.h (MB_CUR_MAX): Not constant anymore. Get value
|
||||
according to currently used locale for catefory LC_CTYPE by
|
||||
calling the function __ctype_get_mb_cur_max.
|
||||
|
||||
Tue May 28 03:27:46 1996 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* FAQ: Fix some typos.
|
||||
Tell that for Linux the kernel header files are necessary.
|
||||
|
||||
* PROJECTS: New file. List of open jobs for glibc.
|
||||
* Makefile (distribute): Add PROJECTS.
|
||||
|
||||
* crypt/GNUmakefile (headers): New variable. Mention crypt.h.
|
||||
* crypt/crypt.h: Header for crypt functions.
|
||||
|
||||
* elf/elf.h: Add some new constants from recent Cygnus ELF
|
||||
header files.
|
||||
|
||||
* login/getutid_r.c: Test for correct type.
|
||||
Don't depend on ut_type and ut_id unless _HAVE_UT_TYPE and
|
||||
_HAVE_UT_ID resp. are defined.
|
||||
Make really compliant with specification.
|
||||
|
||||
* login/getutline_r.c, login/pututline_r.c: Don't depend on
|
||||
ut_type and ut_id unless _HAVE_UT_TYPE and _HAVE_UT_ID resp. are
|
||||
defined.
|
||||
Make really compliant with specification.
|
||||
|
||||
* login/setutent_r.c: Don't depend on ut_type and ut_id unless
|
||||
_HAVE_UT_TYPE and _HAVE_UT_ID resp. are defined.
|
||||
|
||||
* login/login.c, login/logout.c, login/logwtmp.c: Complete
|
||||
rewrite. Now based on getut*/setut* functions.
|
||||
|
||||
* stdlib/strtol.c: Undo changes of Wed May 22 01:48:54 1996.
|
||||
This prevented using this file in other GNU packages.
|
||||
|
||||
* sysdeps/gnu/utmpbits.h: Define _HAVE_UT_TYPE, _HAVE_UT_ID,
|
||||
and _HAVE_UT_TV because struct utmp has these members.
|
||||
|
||||
* sysdeps/libm-i387/e_exp.S: Correct exp(+-Inf) case.
|
||||
|
||||
* utmp.h: New file. Wrapper around login/utmp.h.
|
||||
|
||||
Tue May 28 13:11:19 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* elf/dl-error.c (struct catch): New type.
|
||||
(catch): New static variable, struct catch *.
|
||||
(catch_env, signalled_errstring, signalled_objname): Variables removed.
|
||||
(_dl_signal_error): If CATCH is non-null, set its errstring and
|
||||
objname members and jump to CATCH->env. If it is null, call
|
||||
_dl_sysdep_fatal with a standard message.
|
||||
* elf/rtld.c (dl_main): Explode `doit' function into dl_main's body.
|
||||
No longer use _dl_catch_error.
|
||||
|
||||
* Makerules (sed-remove-objpfx): Avoid extra space in regexp due to
|
||||
continuation line.
|
||||
|
||||
|
36
FAQ
36
FAQ
@ -102,8 +102,8 @@ from your favourite mirror of prep.ai.mit.edu.
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
[Q5] ``Do I need a special linker or archiver?''
|
||||
|
||||
[A5] {UD} If your native versions are not too buggy you can work with
|
||||
them. But GNU libc works best with GNU binutils.
|
||||
[A5] {UD} If your native versions are not too buggy you can probably
|
||||
work with them. But GNU libc works best with GNU binutils.
|
||||
|
||||
On systems where the native linker does not support weak symbols you
|
||||
will not get a really ISO C compliant C library. Generally speaking
|
||||
@ -119,7 +119,7 @@ Older releases are known to have bugs that affect building the GNU C library.
|
||||
|
||||
[A6] {UD} Yes, there are some more :-).
|
||||
|
||||
* lots of diskspace (for i386-linux this means, e.g., ~70MB)
|
||||
* lots of diskspace (for i386-linux this means, e.g., ~70MB).
|
||||
|
||||
You should avoid compiling on a NFS mounted device. This is very
|
||||
slow.
|
||||
@ -130,6 +130,12 @@ Older releases are known to have bugs that affect building the GNU C library.
|
||||
If you are interested in some more measurements let me know.
|
||||
|
||||
|
||||
* When compiling for Linux:
|
||||
|
||||
+ the header files of the Linux kernel must be available in the
|
||||
search path of the CPP as <linux/*.h> and <asm/*.h>.
|
||||
|
||||
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
[Q7] ``When I run `nm libc.so|grep " U "' on the produced library
|
||||
I still find unresolved symbols? Can this be ok?''
|
||||
@ -138,7 +144,7 @@ Older releases are known to have bugs that affect building the GNU C library.
|
||||
symbols:
|
||||
|
||||
* magic symbols automatically generated by the linker. Names are
|
||||
often like __start_* and __stop_*-
|
||||
often like __start_* and __stop_*
|
||||
|
||||
* symbols resolved by using libgcc.a
|
||||
(__udivdi3, __umoddi3, or similar)
|
||||
@ -161,14 +167,18 @@ and with cleanliness. With the introduction of a new version number these
|
||||
errors now can be corrected. Here is a list of the known source code
|
||||
incompatibilities:
|
||||
|
||||
* _GNU_SOURCE: glibc does not automatically define _GNU_SOURCE. Thus, if a
|
||||
program depends on GNU extensions, it is necessary to compile it with C
|
||||
compiler option -D_GNU_SOURCE, or better, to put `#define _GNU_SOURCE' at
|
||||
the beginning of your source files, before any C library header files are
|
||||
included. This difference normally mainfests itself in the form of
|
||||
missing prototypes and/or data type definitions. Thus, if you get such
|
||||
errors, the first thing you should do is try defining _GNU_SOURCE and see
|
||||
if that makes the problem go away.
|
||||
* _GNU_SOURCE: glibc does not automatically define _GNU_SOURCE. Thus,
|
||||
if a program depends on GNU extensions or some other non-standard
|
||||
functionality, it is necessary to compile it with C compiler option
|
||||
-D_GNU_SOURCE, or better, to put `#define _GNU_SOURCE' at the beginning
|
||||
of your source files, before any C library header files are included.
|
||||
This difference normally manifests itself in the form of missing
|
||||
prototypes and/or data type definitions. Thus, if you get such errors,
|
||||
the first thing you should do is try defining _GNU_SOURCE and see if
|
||||
that makes the problem go away.
|
||||
|
||||
For more information consult the file `NOTES' part of the GNU C
|
||||
library sources.
|
||||
|
||||
* reboot(): GNU libc sanitizes the interface of reboot() to be more
|
||||
compatible with the interface used on other OSes. In particular,
|
||||
@ -209,7 +219,7 @@ Answers were given by:
|
||||
{DMT} David Mosberger-Tang, <davidm@AZStarNet.com>
|
||||
|
||||
Amended by:
|
||||
{RM} Roland McGrath <roland@gnu.ai.mit.edu>
|
||||
{RM} Roland McGrath, <roland@gnu.ai.mit.edu>
|
||||
|
||||
Local Variables:
|
||||
mode:text
|
||||
|
4
Makefile
4
Makefile
@ -222,8 +222,8 @@ parent_echo-distinfo:
|
||||
|
||||
# Make the distribution tarfile.
|
||||
|
||||
distribute := README INSTALL FAQ NOTES COPYING.LIB COPYING NEWS \
|
||||
ChangeLog ChangeLog.[0-9] \
|
||||
distribute := README INSTALL FAQ NOTES NEWS PROJECTS \
|
||||
COPYING.LIB COPYING ChangeLog ChangeLog.[0-9] \
|
||||
Makefile Makeconfig Makerules Rules Make-dist MakeTAGS \
|
||||
extra-lib.mk o-iterator.mk \
|
||||
ansidecl.h mkinstalldirs move-if-change install-sh \
|
||||
|
98
PROJECTS
Normal file
98
PROJECTS
Normal file
@ -0,0 +1,98 @@
|
||||
Open jobs for finishing GNU libc:
|
||||
---------------------------------
|
||||
Status: May 1996
|
||||
|
||||
If you have time and talent to take over any of the jobs below please
|
||||
contact <bug-glibc@prep.ai.mit.edu>
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
[ 1] Port to new platforms or test current version on formerly supported
|
||||
platforms.
|
||||
|
||||
|
||||
[ 2] Test compliance with standards. If you have access to recent
|
||||
standards (IEEE, ISO, ANSI, X/Open, ...) and/or test suites you
|
||||
could do some checks as the goal is to be compliant with all
|
||||
standards if they do not contradict each other.
|
||||
|
||||
|
||||
[ 3] Write translations for the GNU libc message for the so far
|
||||
unsupported languages. GNU libc is fully internationalized and
|
||||
users can immediately benefit from this.
|
||||
|
||||
Take a look at the matrix in
|
||||
ftp://prep.ai.mit.edu/pub/gnu/ABOUT-NLS
|
||||
for the current status (of course better use a mirror of prep).
|
||||
|
||||
|
||||
[ 4] Write wordexp() function; this is described in POSIX.2, The
|
||||
header <wordexp.h> already exists.
|
||||
|
||||
Implementation idea: use some functions from bash.
|
||||
|
||||
|
||||
[ 5] Write reentrent versions of crypt() et.al.
|
||||
|
||||
Implementation idea: Define in <crypt.h>
|
||||
|
||||
struct crypt_data
|
||||
{
|
||||
<... all the needed data ...>
|
||||
};
|
||||
|
||||
and define additional functions
|
||||
|
||||
char *crypt_r (__const char *__key, __const char *__salt,
|
||||
struct crypt_data *__data);
|
||||
|
||||
void setkey_r (__const char *__key, struct crypt_data *__data);
|
||||
|
||||
void encrypt_r (char *__block, int __edflag,
|
||||
struct crypt_data *__data);
|
||||
|
||||
If possible the non-reentrent functions should use the reentrent
|
||||
ones.
|
||||
|
||||
Because of the US export restrictions it might be a good idea if
|
||||
some non-american person does this job.
|
||||
|
||||
|
||||
[ 6] Write `long double' versions of the math functions. This should be
|
||||
done in collaboration with the NetBSD and FreeBSD people.
|
||||
|
||||
The libm is in fact fdlibm (not the same as in Linux libc).
|
||||
|
||||
|
||||
[ 7] If you enjoy assembler programming (as I do --drepper :-) you might
|
||||
be interested in writing optimized versions for some functions.
|
||||
Especially the string handling functions can be optimized a lot.
|
||||
|
||||
Take a look at
|
||||
|
||||
Faster String Functions
|
||||
Henry Spencer, University of Toronto
|
||||
Usenix Winter '92, pp. 419--428
|
||||
|
||||
or just ask. Currently mostly i?86 optimized versions exist.
|
||||
|
||||
|
||||
[ 8] Write nftw() function. Perhaps it might be good to reimplement the
|
||||
ftw() function as well to share most of the code.
|
||||
|
||||
|
||||
[ 9] Write AVL-tree based tsearch() et.al. functions. Currently only
|
||||
a very simple algorithm is used.
|
||||
|
||||
|
||||
[10] Extend regex and/or rx to work with wide characters.
|
||||
|
||||
|
||||
[11] Add mmap() support to malloc().
|
||||
Doug Lea's malloc implementation might give some ideas. Perhaps
|
||||
switching completly to his implementation is an option if it
|
||||
a) can work without mmap() support (not all system GNU libc
|
||||
is running on have mmap)
|
||||
b) is without mmap support at least as fast as the current
|
||||
implementation
|
||||
c) will be extended with the current hooks and additional functions
|
@ -1,5 +1,5 @@
|
||||
/* Error handling for runtime dynamic linker.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -20,18 +20,47 @@ Cambridge, MA 02139, USA. */
|
||||
#include <stddef.h>
|
||||
#include <link.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
/* This structure communicates state between _dl_catch_error and
|
||||
_dl_signal_error. */
|
||||
struct catch
|
||||
{
|
||||
const char *errstring, *objname; /* Error detail filled in here. */
|
||||
jmp_buf env; /* longjmp here on error. */
|
||||
};
|
||||
|
||||
/* This points to such a structure during a call to _dl_catch_error.
|
||||
During implicit startup and run-time work for needed shared libraries,
|
||||
this is null. */
|
||||
static struct catch *catch;
|
||||
|
||||
static jmp_buf catch_env;
|
||||
static const char *signalled_errstring, *signalled_objname;
|
||||
|
||||
void
|
||||
_dl_signal_error (int errcode,
|
||||
const char *objname,
|
||||
const char *errstring)
|
||||
{
|
||||
signalled_errstring = errstring ?: "DYNAMIC LINKER BUG!!!";
|
||||
signalled_objname = objname;
|
||||
longjmp (catch_env, errcode ?: -1);
|
||||
if (! errstring)
|
||||
errstring = "DYNAMIC LINKER BUG!!!";
|
||||
|
||||
if (catch)
|
||||
{
|
||||
/* We are inside _dl_catch_error. Return to it. */
|
||||
catch->errstring = errstring;
|
||||
catch->objname = objname;
|
||||
longjmp (catch->env, errcode ?: -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Lossage while resolving the program's own symbols is always fatal. */
|
||||
extern char **_dl_argv; /* Set in rtld.c at startup. */
|
||||
_dl_sysdep_fatal (_dl_argv[0] ?: "<program name unknown>",
|
||||
": error in loading shared libraries\n",
|
||||
objname ?: "", objname ? ": " : "",
|
||||
errstring, errcode ? ": " : "",
|
||||
errcode ? strerror (errcode) : "", "\n", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@ -40,18 +69,20 @@ _dl_catch_error (const char **errstring,
|
||||
void (*operate) (void))
|
||||
{
|
||||
int errcode;
|
||||
struct catch c = { errstring: NULL, objname: NULL };
|
||||
|
||||
signalled_errstring = signalled_objname = NULL;
|
||||
errcode = setjmp (catch_env);
|
||||
errcode = setjmp (c.env);
|
||||
if (errcode == 0)
|
||||
{
|
||||
catch = &c;
|
||||
(*operate) ();
|
||||
catch = NULL;
|
||||
*errstring = *objname = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We get here only if we longjmp'd out of OPERATE. */
|
||||
*errstring = signalled_errstring;
|
||||
*objname = signalled_objname;
|
||||
*errstring = c.errstring;
|
||||
*objname = c.objname;
|
||||
return errcode == -1 ? 0 : errcode;
|
||||
}
|
||||
|
54
elf/elf.h
54
elf/elf.h
@ -119,6 +119,7 @@ typedef struct
|
||||
#define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */
|
||||
|
||||
#define EM_PARISC 15 /* HPPA */
|
||||
#define EM_PPC 20 /* PowerPC */
|
||||
|
||||
/* If it is necessary to assign new unofficial EM_* values, please
|
||||
pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
|
||||
@ -255,6 +256,10 @@ typedef struct
|
||||
#define ELF32_R_TYPE(val) ((val) & 0xff)
|
||||
#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
|
||||
|
||||
#define ELF64_R_SYM(i) ((i) >> 32)
|
||||
#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
|
||||
#define ELF64_R_INFO(sym,type) (((sym) << 32) + (type))
|
||||
|
||||
/* Program segment header. */
|
||||
|
||||
typedef struct {
|
||||
@ -288,6 +293,17 @@ typedef struct {
|
||||
#define PF_R (1 << 2) /* Segment is readable */
|
||||
#define PF_MASKPROC 0xf0000000 /* Processor-specific */
|
||||
|
||||
/* Legal values for note segment descriptor types for core files. */
|
||||
|
||||
#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
|
||||
#define NT_FPREGSET 2 /* Contains copy of fpregset struct */
|
||||
#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */
|
||||
|
||||
/* Legal values for the note segment descriptor types for object files. */
|
||||
|
||||
#define NT_VERSION 1 /* Contains a version string. */
|
||||
|
||||
|
||||
/* Dynamic section entry. */
|
||||
|
||||
typedef struct
|
||||
@ -521,9 +537,17 @@ typedef struct
|
||||
#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */
|
||||
#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */
|
||||
|
||||
/* Legal values for MIPS architecture level. */
|
||||
|
||||
#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
|
||||
#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */
|
||||
#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */
|
||||
|
||||
/* Special section indices. */
|
||||
|
||||
#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */
|
||||
#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbol. */
|
||||
#define SHN_MIPS_DATA 0xff02 /* Allocated data symbol. */
|
||||
#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */
|
||||
#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */
|
||||
|
||||
@ -535,6 +559,9 @@ typedef struct
|
||||
#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */
|
||||
#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information */
|
||||
#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */
|
||||
#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */
|
||||
#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */
|
||||
#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */
|
||||
|
||||
/* Legal values for sh_flags field of Elf32_Shdr. */
|
||||
|
||||
@ -602,7 +629,8 @@ typedef struct
|
||||
#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */
|
||||
#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */
|
||||
#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */
|
||||
#define DT_MIPS_NUM 0x15
|
||||
#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */
|
||||
#define DT_MIPS_NUM 0x17
|
||||
|
||||
/* Legal values for DT_MIPS_FLAG Elf32_Dyn entry. */
|
||||
|
||||
@ -632,4 +660,28 @@ typedef struct
|
||||
typedef Elf32_Addr Elf32_Conflict;
|
||||
|
||||
|
||||
/* HPPA specific definitions. */
|
||||
|
||||
/* Legal values for sh_type field of Elf32_Shdr. */
|
||||
|
||||
#define SHT_PARISC_GOT 0x70000000 /* GOT for external data. */
|
||||
#define SHT_PARISC_ARCH 0x70000001 /* Architecture extensions. */
|
||||
#define SHT_PARISC_GLOBAL 0x70000002 /* Definition of $global$. */
|
||||
#define SHT_PARISC_MILLI 0x70000003 /* Millicode routines. */
|
||||
#define SHT_PARISC_UNWIND 0x70000004 /* Unwind information. */
|
||||
#define SHT_PARISC_PLT 0x70000005 /* Procedure linkage table. */
|
||||
#define SHT_PARISC_SDATA 0x70000006 /* Short initialized data. */
|
||||
#define SHT_PARISC_SBSS 0x70000007 /* Short uninitialized data. */
|
||||
#define SHT_PARISC_SYMEXTN 0x70000008 /* Argument/relocation info. */
|
||||
#define SHT_PARISC_STUBS 0x70000009 /* Linker stubs. */
|
||||
|
||||
/* Legal values for sh_flags field of Elf32_Shdr. */
|
||||
|
||||
#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */
|
||||
|
||||
/* Legal values for ST_TYPE subfield of st_info (symbol type). */
|
||||
|
||||
#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */
|
||||
|
||||
|
||||
#endif /* elf.h */
|
||||
|
486
elf/rtld.c
486
elf/rtld.c
@ -123,33 +123,31 @@ dl_main (const Elf32_Phdr *phdr,
|
||||
Elf32_Word phent,
|
||||
Elf32_Addr *user_entry)
|
||||
{
|
||||
void doit (void)
|
||||
const Elf32_Phdr *ph;
|
||||
struct link_map *l, *last, *before_rtld;
|
||||
const char *interpreter_name;
|
||||
int lazy;
|
||||
int list_only = 0;
|
||||
|
||||
if (*user_entry == (Elf32_Addr) &_start)
|
||||
{
|
||||
const Elf32_Phdr *ph;
|
||||
struct link_map *l, *last, *before_rtld;
|
||||
const char *interpreter_name;
|
||||
int lazy;
|
||||
int list_only = 0;
|
||||
/* Ho ho. We are not the program interpreter! We are the program
|
||||
itself! This means someone ran ld.so as a command. Well, that
|
||||
might be convenient to do sometimes. We support it by
|
||||
interpreting the args like this:
|
||||
|
||||
if (*user_entry == (Elf32_Addr) &_start)
|
||||
{
|
||||
/* Ho ho. We are not the program interpreter! We are the program
|
||||
itself! This means someone ran ld.so as a command. Well, that
|
||||
might be convenient to do sometimes. We support it by
|
||||
interpreting the args like this:
|
||||
ld.so PROGRAM ARGS...
|
||||
|
||||
ld.so PROGRAM ARGS...
|
||||
|
||||
The first argument is the name of a file containing an ELF
|
||||
executable we will load and run with the following arguments.
|
||||
To simplify life here, PROGRAM is searched for using the
|
||||
normal rules for shared objects, rather than $PATH or anything
|
||||
like that. We just load it and use its entry point; we don't
|
||||
pay attention to its PT_INTERP command (we are the interpreter
|
||||
ourselves). This is an easy way to test a new ld.so before
|
||||
installing it. */
|
||||
if (_dl_argc < 2)
|
||||
_dl_sysdep_fatal ("\
|
||||
The first argument is the name of a file containing an ELF
|
||||
executable we will load and run with the following arguments.
|
||||
To simplify life here, PROGRAM is searched for using the
|
||||
normal rules for shared objects, rather than $PATH or anything
|
||||
like that. We just load it and use its entry point; we don't
|
||||
pay attention to its PT_INTERP command (we are the interpreter
|
||||
ourselves). This is an easy way to test a new ld.so before
|
||||
installing it. */
|
||||
if (_dl_argc < 2)
|
||||
_dl_sysdep_fatal ("\
|
||||
Usage: ld.so [--list] EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]\n\
|
||||
You have invoked `ld.so', the helper program for shared library executables.\n\
|
||||
This program usually lives in the file `/lib/ld.so', and special directives\n\
|
||||
@ -162,243 +160,231 @@ that file itself, but always uses this helper program from the file you\n\
|
||||
specified, instead of the helper program file specified in the executable\n\
|
||||
file you run. This is mostly of use for maintainers to test new versions\n\
|
||||
of this helper program; chances are you did not intend to run this program.\n",
|
||||
NULL);
|
||||
NULL);
|
||||
|
||||
interpreter_name = _dl_argv[0];
|
||||
interpreter_name = _dl_argv[0];
|
||||
|
||||
if (! strcmp (_dl_argv[1], "--list"))
|
||||
{
|
||||
list_only = 1;
|
||||
|
||||
++_dl_skip_args;
|
||||
--_dl_argc;
|
||||
++_dl_argv;
|
||||
}
|
||||
if (! strcmp (_dl_argv[1], "--list"))
|
||||
{
|
||||
list_only = 1;
|
||||
|
||||
++_dl_skip_args;
|
||||
--_dl_argc;
|
||||
++_dl_argv;
|
||||
|
||||
l = _dl_map_object (NULL, _dl_argv[0]);
|
||||
phdr = l->l_phdr;
|
||||
phent = l->l_phnum;
|
||||
l->l_name = (char *) "";
|
||||
*user_entry = l->l_entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create a link_map for the executable itself.
|
||||
This will be what dlopen on "" returns. */
|
||||
l = _dl_new_object ((char *) "", "", lt_executable);
|
||||
l->l_phdr = phdr;
|
||||
l->l_phnum = phent;
|
||||
interpreter_name = 0;
|
||||
l->l_entry = *user_entry;
|
||||
}
|
||||
|
||||
if (l != _dl_loaded)
|
||||
{
|
||||
/* GDB assumes that the first element on the chain is the
|
||||
link_map for the executable itself, and always skips it.
|
||||
Make sure the first one is indeed that one. */
|
||||
l->l_prev->l_next = l->l_next;
|
||||
if (l->l_next)
|
||||
l->l_next->l_prev = l->l_prev;
|
||||
l->l_prev = NULL;
|
||||
l->l_next = _dl_loaded;
|
||||
_dl_loaded->l_prev = l;
|
||||
_dl_loaded = l;
|
||||
}
|
||||
++_dl_skip_args;
|
||||
--_dl_argc;
|
||||
++_dl_argv;
|
||||
|
||||
/* Scan the program header table for the dynamic section. */
|
||||
for (ph = phdr; ph < &phdr[phent]; ++ph)
|
||||
switch (ph->p_type)
|
||||
{
|
||||
case PT_DYNAMIC:
|
||||
/* This tells us where to find the dynamic section,
|
||||
which tells us everything we need to do. */
|
||||
l->l_ld = (void *) l->l_addr + ph->p_vaddr;
|
||||
break;
|
||||
case PT_INTERP:
|
||||
/* This "interpreter segment" was used by the program loader to
|
||||
find the program interpreter, which is this program itself, the
|
||||
dynamic linker. We note what name finds us, so that a future
|
||||
dlopen call or DT_NEEDED entry, for something that wants to link
|
||||
against the dynamic linker as a shared library, will know that
|
||||
the shared object is already loaded. */
|
||||
interpreter_name = (void *) l->l_addr + ph->p_vaddr;
|
||||
break;
|
||||
}
|
||||
assert (interpreter_name); /* How else did we get here? */
|
||||
|
||||
/* Extract the contents of the dynamic section for easy access. */
|
||||
elf_get_dynamic_info (l->l_ld, l->l_info);
|
||||
if (l->l_info[DT_HASH])
|
||||
/* Set up our cache of pointers into the hash table. */
|
||||
_dl_setup_hash (l);
|
||||
|
||||
if (l->l_info[DT_DEBUG])
|
||||
/* There is a DT_DEBUG entry in the dynamic section. Fill it in
|
||||
with the run-time address of the r_debug structure, which we
|
||||
will set up later to communicate with the debugger. */
|
||||
l->l_info[DT_DEBUG]->d_un.d_ptr = (Elf32_Addr) &dl_r_debug;
|
||||
|
||||
/* Put the link_map for ourselves on the chain so it can be found by
|
||||
name. */
|
||||
rtld_map.l_name = (char *) rtld_map.l_libname = interpreter_name;
|
||||
rtld_map.l_type = lt_interpreter;
|
||||
while (l->l_next)
|
||||
l = l->l_next;
|
||||
l->l_next = &rtld_map;
|
||||
rtld_map.l_prev = l;
|
||||
|
||||
/* Now process all the DT_NEEDED entries and map in the objects.
|
||||
Each new link_map will go on the end of the chain, so we will
|
||||
come across it later in the loop to map in its dependencies. */
|
||||
before_rtld = NULL;
|
||||
for (l = _dl_loaded; l; l = l->l_next)
|
||||
{
|
||||
if (l->l_info[DT_NEEDED])
|
||||
{
|
||||
const char *strtab
|
||||
= (void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr;
|
||||
const Elf32_Dyn *d;
|
||||
last = l;
|
||||
for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
|
||||
if (d->d_tag == DT_NEEDED)
|
||||
{
|
||||
struct link_map *new;
|
||||
new = _dl_map_object (l, strtab + d->d_un.d_val);
|
||||
if (!before_rtld && new == &rtld_map)
|
||||
before_rtld = last;
|
||||
last = new;
|
||||
}
|
||||
}
|
||||
l->l_deps_loaded = 1;
|
||||
}
|
||||
|
||||
/* If any DT_NEEDED entry referred to the interpreter object itself,
|
||||
reorder the list so it appears after its dependent. If not,
|
||||
remove it from the maps we will use for symbol resolution. */
|
||||
rtld_map.l_prev->l_next = rtld_map.l_next;
|
||||
if (rtld_map.l_next)
|
||||
rtld_map.l_next->l_prev = rtld_map.l_prev;
|
||||
if (before_rtld)
|
||||
{
|
||||
rtld_map.l_prev = before_rtld;
|
||||
rtld_map.l_next = before_rtld->l_next;
|
||||
before_rtld->l_next = &rtld_map;
|
||||
if (rtld_map.l_next)
|
||||
rtld_map.l_next->l_prev = &rtld_map;
|
||||
}
|
||||
|
||||
if (list_only)
|
||||
{
|
||||
/* We were run just to list the shared libraries. It is
|
||||
important that we do this before real relocation, because the
|
||||
functions we call below for output may no longer work properly
|
||||
after relocation. */
|
||||
|
||||
int i;
|
||||
|
||||
if (! _dl_loaded->l_info[DT_NEEDED])
|
||||
_dl_sysdep_message ("\t", "statically linked\n", NULL);
|
||||
else
|
||||
for (l = _dl_loaded->l_next; l; l = l->l_next)
|
||||
{
|
||||
char buf[20], *bp;
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
bp = _itoa (l->l_addr, &buf[sizeof buf - 1], 16, 0);
|
||||
while (&buf[sizeof buf - 1] - bp < sizeof l->l_addr * 2)
|
||||
*--bp = '0';
|
||||
_dl_sysdep_message ("\t", l->l_libname, " => ", l->l_name,
|
||||
" (0x", bp, ")\n", NULL);
|
||||
}
|
||||
|
||||
for (i = 1; i < _dl_argc; ++i)
|
||||
{
|
||||
const Elf32_Sym *ref = NULL;
|
||||
Elf32_Addr loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
|
||||
_dl_loaded, "argument",
|
||||
1);
|
||||
char buf[20], *bp;
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0);
|
||||
while (&buf[sizeof buf - 1] - bp < sizeof loadbase * 2)
|
||||
*--bp = '0';
|
||||
_dl_sysdep_message (_dl_argv[i], " found at 0x", bp, NULL);
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
bp = _itoa (loadbase, &buf[sizeof buf - 1], 16, 0);
|
||||
while (&buf[sizeof buf - 1] - bp < sizeof loadbase * 2)
|
||||
*--bp = '0';
|
||||
_dl_sysdep_message (" in object at 0x", bp, "\n", NULL);
|
||||
}
|
||||
|
||||
_exit (0);
|
||||
}
|
||||
|
||||
lazy = !_dl_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
|
||||
|
||||
/* Now we have all the objects loaded. Relocate them all except for
|
||||
the dynamic linker itself. We do this in reverse order so that
|
||||
copy relocs of earlier objects overwrite the data written by later
|
||||
objects. We do not re-relocate the dynamic linker itself in this
|
||||
loop because that could result in the GOT entries for functions we
|
||||
call being changed, and that would break us. It is safe to
|
||||
relocate the dynamic linker out of order because it has no copy
|
||||
relocs (we know that because it is self-contained). */
|
||||
l = _dl_loaded;
|
||||
while (l->l_next)
|
||||
l = l->l_next;
|
||||
do
|
||||
{
|
||||
if (l != &rtld_map)
|
||||
_dl_relocate_object (l, lazy);
|
||||
l = l->l_prev;
|
||||
} while (l);
|
||||
|
||||
/* Do any necessary cleanups for the startup OS interface code.
|
||||
We do these now so that no calls are made after rtld re-relocation
|
||||
which might be resolved to different functions than we expect.
|
||||
We cannot do this before relocating the other objects because
|
||||
_dl_relocate_object might need to call `mprotect' for DT_TEXTREL. */
|
||||
_dl_sysdep_start_cleanup ();
|
||||
|
||||
if (rtld_map.l_opencount > 0)
|
||||
/* There was an explicit ref to the dynamic linker as a shared lib.
|
||||
Re-relocate ourselves with user-controlled symbol definitions. */
|
||||
_dl_relocate_object (&rtld_map, lazy);
|
||||
|
||||
/* Tell the debugger where to find the map of loaded objects. */
|
||||
dl_r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */;
|
||||
dl_r_debug.r_ldbase = rtld_map.l_addr; /* Record our load address. */
|
||||
dl_r_debug.r_map = _dl_loaded;
|
||||
dl_r_debug.r_brk = (Elf32_Addr) &_dl_r_debug_state;
|
||||
|
||||
if (rtld_map.l_info[DT_INIT])
|
||||
{
|
||||
/* Call the initializer for the compatibility version of the
|
||||
dynamic linker. There is no additional initialization
|
||||
required for the ABI-compliant dynamic linker. */
|
||||
|
||||
(*(void (*) (void)) (rtld_map.l_addr +
|
||||
rtld_map.l_info[DT_INIT]->d_un.d_ptr)) ();
|
||||
|
||||
/* Clear the field so a future dlopen won't run it again. */
|
||||
rtld_map.l_info[DT_INIT] = NULL;
|
||||
}
|
||||
l = _dl_map_object (NULL, _dl_argv[0]);
|
||||
phdr = l->l_phdr;
|
||||
phent = l->l_phnum;
|
||||
l->l_name = (char *) "";
|
||||
*user_entry = l->l_entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create a link_map for the executable itself.
|
||||
This will be what dlopen on "" returns. */
|
||||
l = _dl_new_object ((char *) "", "", lt_executable);
|
||||
l->l_phdr = phdr;
|
||||
l->l_phnum = phent;
|
||||
interpreter_name = 0;
|
||||
l->l_entry = *user_entry;
|
||||
}
|
||||
const char *errstring;
|
||||
const char *errobj;
|
||||
int err;
|
||||
|
||||
err = _dl_catch_error (&errstring, &errobj, &doit);
|
||||
if (errstring)
|
||||
_dl_sysdep_fatal (_dl_argv[0] ?: "<program name unknown>",
|
||||
": error in loading shared libraries\n",
|
||||
errobj ?: "", errobj ? ": " : "",
|
||||
errstring, err ? ": " : "",
|
||||
err ? strerror (err) : "", "\n", NULL);
|
||||
if (l != _dl_loaded)
|
||||
{
|
||||
/* GDB assumes that the first element on the chain is the
|
||||
link_map for the executable itself, and always skips it.
|
||||
Make sure the first one is indeed that one. */
|
||||
l->l_prev->l_next = l->l_next;
|
||||
if (l->l_next)
|
||||
l->l_next->l_prev = l->l_prev;
|
||||
l->l_prev = NULL;
|
||||
l->l_next = _dl_loaded;
|
||||
_dl_loaded->l_prev = l;
|
||||
_dl_loaded = l;
|
||||
}
|
||||
|
||||
/* Scan the program header table for the dynamic section. */
|
||||
for (ph = phdr; ph < &phdr[phent]; ++ph)
|
||||
switch (ph->p_type)
|
||||
{
|
||||
case PT_DYNAMIC:
|
||||
/* This tells us where to find the dynamic section,
|
||||
which tells us everything we need to do. */
|
||||
l->l_ld = (void *) l->l_addr + ph->p_vaddr;
|
||||
break;
|
||||
case PT_INTERP:
|
||||
/* This "interpreter segment" was used by the program loader to
|
||||
find the program interpreter, which is this program itself, the
|
||||
dynamic linker. We note what name finds us, so that a future
|
||||
dlopen call or DT_NEEDED entry, for something that wants to link
|
||||
against the dynamic linker as a shared library, will know that
|
||||
the shared object is already loaded. */
|
||||
interpreter_name = (void *) l->l_addr + ph->p_vaddr;
|
||||
break;
|
||||
}
|
||||
assert (interpreter_name); /* How else did we get here? */
|
||||
|
||||
/* Extract the contents of the dynamic section for easy access. */
|
||||
elf_get_dynamic_info (l->l_ld, l->l_info);
|
||||
if (l->l_info[DT_HASH])
|
||||
/* Set up our cache of pointers into the hash table. */
|
||||
_dl_setup_hash (l);
|
||||
|
||||
if (l->l_info[DT_DEBUG])
|
||||
/* There is a DT_DEBUG entry in the dynamic section. Fill it in
|
||||
with the run-time address of the r_debug structure, which we
|
||||
will set up later to communicate with the debugger. */
|
||||
l->l_info[DT_DEBUG]->d_un.d_ptr = (Elf32_Addr) &dl_r_debug;
|
||||
|
||||
/* Put the link_map for ourselves on the chain so it can be found by
|
||||
name. */
|
||||
rtld_map.l_name = (char *) rtld_map.l_libname = interpreter_name;
|
||||
rtld_map.l_type = lt_interpreter;
|
||||
while (l->l_next)
|
||||
l = l->l_next;
|
||||
l->l_next = &rtld_map;
|
||||
rtld_map.l_prev = l;
|
||||
|
||||
/* Now process all the DT_NEEDED entries and map in the objects.
|
||||
Each new link_map will go on the end of the chain, so we will
|
||||
come across it later in the loop to map in its dependencies. */
|
||||
before_rtld = NULL;
|
||||
for (l = _dl_loaded; l; l = l->l_next)
|
||||
{
|
||||
if (l->l_info[DT_NEEDED])
|
||||
{
|
||||
const char *strtab
|
||||
= (void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr;
|
||||
const Elf32_Dyn *d;
|
||||
last = l;
|
||||
for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
|
||||
if (d->d_tag == DT_NEEDED)
|
||||
{
|
||||
struct link_map *new;
|
||||
new = _dl_map_object (l, strtab + d->d_un.d_val);
|
||||
if (!before_rtld && new == &rtld_map)
|
||||
before_rtld = last;
|
||||
last = new;
|
||||
}
|
||||
}
|
||||
l->l_deps_loaded = 1;
|
||||
}
|
||||
|
||||
/* If any DT_NEEDED entry referred to the interpreter object itself,
|
||||
reorder the list so it appears after its dependent. If not,
|
||||
remove it from the maps we will use for symbol resolution. */
|
||||
rtld_map.l_prev->l_next = rtld_map.l_next;
|
||||
if (rtld_map.l_next)
|
||||
rtld_map.l_next->l_prev = rtld_map.l_prev;
|
||||
if (before_rtld)
|
||||
{
|
||||
rtld_map.l_prev = before_rtld;
|
||||
rtld_map.l_next = before_rtld->l_next;
|
||||
before_rtld->l_next = &rtld_map;
|
||||
if (rtld_map.l_next)
|
||||
rtld_map.l_next->l_prev = &rtld_map;
|
||||
}
|
||||
|
||||
if (list_only)
|
||||
{
|
||||
/* We were run just to list the shared libraries. It is
|
||||
important that we do this before real relocation, because the
|
||||
functions we call below for output may no longer work properly
|
||||
after relocation. */
|
||||
|
||||
int i;
|
||||
|
||||
if (! _dl_loaded->l_info[DT_NEEDED])
|
||||
_dl_sysdep_message ("\t", "statically linked\n", NULL);
|
||||
else
|
||||
for (l = _dl_loaded->l_next; l; l = l->l_next)
|
||||
{
|
||||
char buf[20], *bp;
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
bp = _itoa (l->l_addr, &buf[sizeof buf - 1], 16, 0);
|
||||
while (&buf[sizeof buf - 1] - bp < sizeof l->l_addr * 2)
|
||||
*--bp = '0';
|
||||
_dl_sysdep_message ("\t", l->l_libname, " => ", l->l_name,
|
||||
" (0x", bp, ")\n", NULL);
|
||||
}
|
||||
|
||||
for (i = 1; i < _dl_argc; ++i)
|
||||
{
|
||||
const Elf32_Sym *ref = NULL;
|
||||
Elf32_Addr loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
|
||||
_dl_loaded, "argument",
|
||||
1);
|
||||
char buf[20], *bp;
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0);
|
||||
while (&buf[sizeof buf - 1] - bp < sizeof loadbase * 2)
|
||||
*--bp = '0';
|
||||
_dl_sysdep_message (_dl_argv[i], " found at 0x", bp, NULL);
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
bp = _itoa (loadbase, &buf[sizeof buf - 1], 16, 0);
|
||||
while (&buf[sizeof buf - 1] - bp < sizeof loadbase * 2)
|
||||
*--bp = '0';
|
||||
_dl_sysdep_message (" in object at 0x", bp, "\n", NULL);
|
||||
}
|
||||
|
||||
_exit (0);
|
||||
}
|
||||
|
||||
lazy = !_dl_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
|
||||
|
||||
/* Now we have all the objects loaded. Relocate them all except for
|
||||
the dynamic linker itself. We do this in reverse order so that
|
||||
copy relocs of earlier objects overwrite the data written by later
|
||||
objects. We do not re-relocate the dynamic linker itself in this
|
||||
loop because that could result in the GOT entries for functions we
|
||||
call being changed, and that would break us. It is safe to
|
||||
relocate the dynamic linker out of order because it has no copy
|
||||
relocs (we know that because it is self-contained). */
|
||||
l = _dl_loaded;
|
||||
while (l->l_next)
|
||||
l = l->l_next;
|
||||
do
|
||||
{
|
||||
if (l != &rtld_map)
|
||||
_dl_relocate_object (l, lazy);
|
||||
l = l->l_prev;
|
||||
} while (l);
|
||||
|
||||
/* Do any necessary cleanups for the startup OS interface code.
|
||||
We do these now so that no calls are made after rtld re-relocation
|
||||
which might be resolved to different functions than we expect.
|
||||
We cannot do this before relocating the other objects because
|
||||
_dl_relocate_object might need to call `mprotect' for DT_TEXTREL. */
|
||||
_dl_sysdep_start_cleanup ();
|
||||
|
||||
if (rtld_map.l_opencount > 0)
|
||||
/* There was an explicit ref to the dynamic linker as a shared lib.
|
||||
Re-relocate ourselves with user-controlled symbol definitions. */
|
||||
_dl_relocate_object (&rtld_map, lazy);
|
||||
|
||||
/* Tell the debugger where to find the map of loaded objects. */
|
||||
dl_r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */;
|
||||
dl_r_debug.r_ldbase = rtld_map.l_addr; /* Record our load address. */
|
||||
dl_r_debug.r_map = _dl_loaded;
|
||||
dl_r_debug.r_brk = (Elf32_Addr) &_dl_r_debug_state;
|
||||
|
||||
if (rtld_map.l_info[DT_INIT])
|
||||
{
|
||||
/* Call the initializer for the compatibility version of the
|
||||
dynamic linker. There is no additional initialization
|
||||
required for the ABI-compliant dynamic linker. */
|
||||
|
||||
(*(void (*) (void)) (rtld_map.l_addr +
|
||||
rtld_map.l_info[DT_INIT]->d_un.d_ptr)) ();
|
||||
|
||||
/* Clear the field so a future dlopen won't run it again. */
|
||||
rtld_map.l_info[DT_INIT] = NULL;
|
||||
}
|
||||
|
||||
/* Once we return, _dl_sysdep_start will invoke
|
||||
the DT_INIT functions and then *USER_ENTRY. */
|
||||
|
7
limits.h
7
limits.h
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -59,9 +59,8 @@ Cambridge, MA 02139, USA. */
|
||||
/* Number of bits in a `char'. */
|
||||
#define CHAR_BIT 8
|
||||
|
||||
/* Maximum length of any multibyte character in any locale.
|
||||
Locale-writers should change this as necessary. */
|
||||
#define MB_LEN_MAX 1
|
||||
/* Maximum length of any multibyte character in any locale. */
|
||||
#define MB_LEN_MAX 6
|
||||
|
||||
/* Minimum and maximum values a `signed char' can hold. */
|
||||
#define SCHAR_MIN (-128)
|
||||
|
@ -898,7 +898,7 @@ const struct locale_data _nl_C_LC_CTYPE =
|
||||
{
|
||||
_nl_C_name,
|
||||
NULL, 0, /* no file mapped */
|
||||
13,
|
||||
14,
|
||||
{
|
||||
{ string: _nl_C_LC_CTYPE_class },
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
@ -919,6 +919,7 @@ const struct locale_data _nl_C_LC_CTYPE =
|
||||
{ string: "upper\0" "lower\0" "alpha\0" "digit\0" "xdigit\0" "space\0"
|
||||
"print\0" "graph\0" "blank\0" "cntrl\0" "punct\0" "alnum\0" },
|
||||
{ string: "tolower\0" "toupper\0" },
|
||||
{ string: _nl_C_LC_CTYPE_width }
|
||||
{ string: _nl_C_LC_CTYPE_width },
|
||||
{ word: 2 }
|
||||
}
|
||||
};
|
||||
|
@ -28,7 +28,8 @@ distribute = localeinfo.h categories.def \
|
||||
charmap-kw.gperf charmap-kw.h locfile-token.h \
|
||||
locfile-kw.gperf locfile-kw.h linereader.h \
|
||||
locales.h locfile.h stringtrans.h
|
||||
routines = setlocale findlocale loadlocale localeconv nl_langinfo
|
||||
routines = setlocale findlocale loadlocale localeconv nl_langinfo \
|
||||
mb_cur_max
|
||||
categories = ctype messages monetary numeric time collate
|
||||
aux = $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name
|
||||
others = localedef locale
|
||||
|
@ -74,6 +74,7 @@ DEFINE_CATEGORY
|
||||
DEFINE_ELEMENT (_NL_CTYPE_CLASS_NAMES, "ctype-class-names", std, string)
|
||||
DEFINE_ELEMENT (_NL_CTYPE_MAP_NAMES, "ctype-map-names", std, string)
|
||||
DEFINE_ELEMENT (_NL_CTYPE_WIDTH, "ctype-width", std, bytearray)
|
||||
DEFINE_ELEMENT (_NL_CTYPE_MB_CUR_MAX, "ctype-mb-cur-max", std, word)
|
||||
), _nl_postload_ctype, ctype_input, ctype_check, ctype_output)
|
||||
|
||||
|
||||
|
@ -133,6 +133,7 @@ typedef enum
|
||||
_NL_CTYPE_CLASS_NAMES,
|
||||
_NL_CTYPE_MAP_NAMES,
|
||||
_NL_CTYPE_WIDTH,
|
||||
_NL_CTYPE_MB_CUR_MAX,
|
||||
_NL_NUM_LC_CTYPE,
|
||||
|
||||
/* LC_MONETARY category: formatting of monetary quantities.
|
||||
|
@ -27,7 +27,7 @@ Cambridge, MA 02139, USA. */
|
||||
#include "../intl/loadinfo.h" /* For loaded_l10nfile definition. */
|
||||
|
||||
/* Magic number at the beginning of a locale data file for CATEGORY. */
|
||||
#define LIMAGIC(category) (0x960316de ^ (category))
|
||||
#define LIMAGIC(category) (0x960528de ^ (category))
|
||||
|
||||
/* Two special weight constants for the collation data. */
|
||||
#define FORWARD_CHAR ((wchar_t) 0xfffffffd)
|
||||
|
32
locale/mb_cur_max.c
Normal file
32
locale/mb_cur_max.c
Normal file
@ -0,0 +1,32 @@
|
||||
/* Return number of characters in multibyte representation for current
|
||||
character set.
|
||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <langinfo.h>
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
#include "localeinfo.h"
|
||||
|
||||
|
||||
int
|
||||
__ctype_get_mb_cur_max (void)
|
||||
{
|
||||
return _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MB_CUR_MAX);
|
||||
}
|
@ -108,6 +108,7 @@ struct locale_ctype_t
|
||||
u_int32_t *class_name_ptr;
|
||||
u_int32_t *map_name_ptr;
|
||||
unsigned char *width;
|
||||
u_int32_t mb_cur_max;
|
||||
};
|
||||
|
||||
|
||||
@ -471,6 +472,9 @@ ctype_output (struct localedef_t *locale, struct charset_t *charset,
|
||||
CTYPE_DATA (_NL_CTYPE_WIDTH,
|
||||
ctype->width, ctype->plane_size * ctype->plane_cnt);
|
||||
|
||||
CTYPE_DATA (_NL_CTYPE_MB_CUR_MAX,
|
||||
&ctype->mb_cur_max, sizeof (u_int32_t));
|
||||
|
||||
default:
|
||||
assert (! "unknown CTYPE element");
|
||||
}
|
||||
@ -1372,4 +1376,10 @@ Computing table size for character classes might take a while..."),
|
||||
= charset->width_rules[cnt].width;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute MB_CUR_MAX. Please note the value mb_cur_max in the
|
||||
character set definition gives the number of bytes in the wide
|
||||
character representation. We compute the number of bytes used
|
||||
for the UTF-8 encoded form. */
|
||||
ctype->mb_cur_max = ((int []) { 2, 3, 5, 6 }) [charset->mb_cur_max - 1];
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
|
||||
@ -28,6 +29,18 @@ int
|
||||
getutid_r (const struct utmp *id, struct utmp **utmp,
|
||||
struct utmp_data *utmp_data)
|
||||
{
|
||||
#if (_HAVE_UT_ID - 0) && (_HAVE_UT_TYPE - 0)
|
||||
/* Test whether ID has any of the legal types. */
|
||||
if (id->ut_type != RUN_LVL && id->ut_type != BOOT_TIME
|
||||
&& id->ut_type != OLD_TIME && id->ut_type != NEW_TIME
|
||||
&& id->ut_type != INIT_PROCESS && id->ut_type != LOGIN_PROCESS
|
||||
&& id->ut_type != USER_PROCESS && id->ut_type != DEAD_PROCESS)
|
||||
/* No, using '<' and '>' for the test is not possible. */
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Open utmp file if not already done. */
|
||||
if (utmp_data->ut_fd == -1)
|
||||
{
|
||||
@ -40,7 +53,7 @@ getutid_r (const struct utmp *id, struct utmp **utmp,
|
||||
if (lseek (utmp_data->ut_fd, utmp_data->loc_utmp, SEEK_SET) == -1)
|
||||
return -1;
|
||||
|
||||
do
|
||||
while (1)
|
||||
{
|
||||
/* Read the next entry. */
|
||||
if (read (utmp_data->ut_fd, &utmp_data->ubuf, sizeof (struct utmp))
|
||||
@ -52,10 +65,27 @@ getutid_r (const struct utmp *id, struct utmp **utmp,
|
||||
|
||||
/* Update position pointer. */
|
||||
utmp_data->loc_utmp += sizeof (struct utmp);
|
||||
|
||||
if ((id->ut_type == RUN_LVL || id->ut_type == BOOT_TIME
|
||||
|| id->ut_type == OLD_TIME || id->ut_type == NEW_TIME)
|
||||
&& id->ut_type != utmp_data->ubuf.ut_type)
|
||||
/* Stop at the next entry with type RUN_LVL, BOOT_TIME,
|
||||
OLD_TIME, or NEW_TIME. */
|
||||
break;
|
||||
|
||||
if ((id->ut_type == INIT_PROCESS || id->ut_type == LOGIN_PROCESS
|
||||
|| id->ut_type == USER_PROCESS || id->ut_type == DEAD_PROCESS)
|
||||
&& strncmp (id->ut_id, utmp_data->ubuf.ut_id, sizeof id->ut_id) == 0)
|
||||
/* Stop at the next entry with the specified ID and with type
|
||||
INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, or DEAD_PROCESS. */
|
||||
break;
|
||||
}
|
||||
while (id->ut_type != utmp_data->ubuf.ut_type);
|
||||
|
||||
*utmp = &utmp_data->ubuf;
|
||||
|
||||
return 0;
|
||||
#else /* !_HAVE_UT_ID && !_HAVE_UT_TYPE */
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* For implementing this function we don't use the getutent_r function
|
||||
@ -41,7 +41,7 @@ getutline_r (const struct utmp *line, struct utmp **utmp,
|
||||
if (lseek (utmp_data->ut_fd, utmp_data->loc_utmp, SEEK_SET) == -1)
|
||||
return -1;
|
||||
|
||||
do
|
||||
while (1)
|
||||
{
|
||||
/* Read the next entry. */
|
||||
if (read (utmp_data->ut_fd, &utmp_data->ubuf, sizeof (struct utmp))
|
||||
@ -53,9 +53,24 @@ getutline_r (const struct utmp *line, struct utmp **utmp,
|
||||
|
||||
/* Update position pointer. */
|
||||
utmp_data->loc_utmp += sizeof (struct utmp);
|
||||
|
||||
#if _HAVE_UT_TYPE - 0
|
||||
if (utmp_data->ubuf.ut_type == USER_PROCESS
|
||||
&& strncmp (line->ut_line, utmp_data->ubuf.ut_line,
|
||||
sizeof line->ut_line) == 0)
|
||||
/* Stop if we found an user entry. */
|
||||
break;
|
||||
|
||||
if (utmp_data->ubuf.ut_type == LOGIN_PROCESS)
|
||||
/* Stop if we found a login entry. */
|
||||
break;
|
||||
#else /* !_HAVE_UT_TYPE */
|
||||
if (strncmp (line->ut_line, utmp_data->ubuf.ut_line,
|
||||
sizeof line->ut_line) == 0)
|
||||
/* Stop if the line match. */
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
while (strncmp (line->ut_line, utmp_data->ubuf.ut_line,
|
||||
sizeof line->ut_line));
|
||||
|
||||
*utmp = &utmp_data->ubuf;
|
||||
|
||||
|
140
login/login.c
140
login/login.c
@ -1,63 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)login.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
#include <sys/types.h>
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
#include <fcntl.h>
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <utmp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
void
|
||||
login(ut)
|
||||
const struct utmp *ut;
|
||||
login (const struct utmp *ut)
|
||||
{
|
||||
register int fd;
|
||||
int tty;
|
||||
char tty[PATH_MAX + UT_LINESIZE];
|
||||
int found_tty;
|
||||
const char *ttyp;
|
||||
struct utmp_data data;
|
||||
|
||||
tty = ttyslot();
|
||||
if (tty > 0 && (fd = open(_PATH_UTMP, O_WRONLY|O_CREAT, 0644)) >= 0) {
|
||||
(void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), L_SET);
|
||||
(void)write(fd, ut, sizeof(struct utmp));
|
||||
(void)close(fd);
|
||||
/* Seek tty. */
|
||||
found_tty = ttyname_r (STDIN_FILENO, tty, sizeof tty);
|
||||
if (found_tty < 0)
|
||||
found_tty = ttyname_r (STDOUT_FILENO, tty, sizeof tty);
|
||||
if (found_tty < 0)
|
||||
found_tty = ttyname_r (STDERR_FILENO, tty, sizeof tty);
|
||||
|
||||
if (found_tty >= 0)
|
||||
{
|
||||
/* Tell that we want to use the UTMP file. */
|
||||
if (utmpname (_PATH_UTMP) != 0)
|
||||
{
|
||||
struct utmp tmp;
|
||||
struct utmp *old;
|
||||
|
||||
/* Open UTMP file. */
|
||||
setutent_r (&data);
|
||||
|
||||
/* We only want to insert the name of the tty without path. */
|
||||
ttyp = basename (tty);
|
||||
|
||||
/* Position to record for this tty. */
|
||||
#if _HAVE_UT_TYPE - 0
|
||||
tmp.ut_type = USER_PROCESS;
|
||||
#endif
|
||||
strncpy (tmp.ut_line, ttyp, UT_LINESIZE);
|
||||
|
||||
/* Read the record. */
|
||||
if (getutline_r (&tmp, &old, &data) >= 0 || errno == ESRCH)
|
||||
{
|
||||
#if _HAVE_UT_TYPE - 0
|
||||
/* We have to fake the old entry because this `login'
|
||||
function does not fit well into the UTMP file
|
||||
handling scheme. */
|
||||
old->ut_type = ut->ut_type;
|
||||
#endif
|
||||
pututline_r (ut, &data);
|
||||
}
|
||||
|
||||
/* Close UTMP file. */
|
||||
endutent_r (&data);
|
||||
}
|
||||
if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
|
||||
(void)write(fd, ut, sizeof(struct utmp));
|
||||
(void)close(fd);
|
||||
}
|
||||
|
||||
/* Update the WTMP file. Here we have to add a new entry. */
|
||||
if (utmpname (_PATH_WTMP) != 0)
|
||||
{
|
||||
/* Open the WTMP file. */
|
||||
setutent_r (&data);
|
||||
|
||||
/* Position at end of file. */
|
||||
data.loc_utmp = lseek (data.ut_fd, 0, SEEK_END);
|
||||
if (data.loc_utmp != -1)
|
||||
{
|
||||
#if _HAVE_UT_TYPE - 0
|
||||
/* We have to fake the old entry because this `login'
|
||||
function does not fit well into the UTMP file handling
|
||||
scheme. */
|
||||
data.ubuf.ut_type = ut->ut_type;
|
||||
#endif
|
||||
pututline_r (ut, &data);
|
||||
}
|
||||
|
||||
/* Close WTMP file. */
|
||||
endutent_r (&data);
|
||||
}
|
||||
}
|
||||
|
123
login/logout.c
123
login/logout.c
@ -1,72 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)logout.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
#include <sys/types.h>
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <utmp.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <utmp.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct utmp UTMP;
|
||||
|
||||
int
|
||||
logout(line)
|
||||
register const char *line;
|
||||
logout (const char *line)
|
||||
{
|
||||
register int fd;
|
||||
UTMP ut;
|
||||
int rval;
|
||||
struct utmp_data data;
|
||||
struct utmp tmp;
|
||||
struct utmp *ut;
|
||||
int result = 0;
|
||||
|
||||
if ((fd = open(_PATH_UTMP, O_RDWR, 0)) < 0)
|
||||
return(0);
|
||||
rval = 0;
|
||||
while (read(fd, &ut, sizeof(UTMP)) == sizeof(UTMP)) {
|
||||
if (!ut.ut_name[0] || strncmp(ut.ut_line, line, UT_LINESIZE))
|
||||
continue;
|
||||
bzero(ut.ut_name, UT_NAMESIZE);
|
||||
bzero(ut.ut_host, UT_HOSTSIZE);
|
||||
(void)time(&ut.ut_time);
|
||||
(void)lseek(fd, -(off_t)sizeof(UTMP), L_INCR);
|
||||
(void)write(fd, &ut, sizeof(UTMP));
|
||||
rval = 1;
|
||||
}
|
||||
(void)close(fd);
|
||||
return(rval);
|
||||
/* Tell that we want to use the UTMP file. */
|
||||
if (utmpname (_PATH_UTMP) == 0)
|
||||
return 0;
|
||||
|
||||
/* Open UTMP file. */
|
||||
setutent_r (&data);
|
||||
|
||||
/* Fill in search information. */
|
||||
#if _HAVE_UT_TYPE - 0
|
||||
tmp.ut_type = USER_PROCESS;
|
||||
#endif
|
||||
strncpy (tmp.ut_line, line, UT_LINESIZE);
|
||||
|
||||
/* Read the record. */
|
||||
if (getutline_r (&tmp, &ut, &data) >= 0 || errno == ESRCH)
|
||||
{
|
||||
/* Clear information about who & from where. */
|
||||
bzero (ut->ut_name, UT_NAMESIZE);
|
||||
bzero (ut->ut_host, UT_HOSTSIZE);
|
||||
|
||||
#if _HAVE_UT_TV - 0
|
||||
gettimeofday (&ut->ut_tv, NULL);
|
||||
#else
|
||||
time (&ut->ut_time);
|
||||
#endif
|
||||
|
||||
if (pututline_r (ut, &data) >= 0)
|
||||
result = 1;
|
||||
}
|
||||
|
||||
/* Close UTMP file. */
|
||||
endutent_r (&data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
115
login/logwtmp.c
115
login/logwtmp.c
@ -1,67 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)logwtmp.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
|
||||
void
|
||||
logwtmp(line, name, host)
|
||||
const char *line, *name, *host;
|
||||
{
|
||||
struct utmp ut;
|
||||
struct stat buf;
|
||||
int fd;
|
||||
|
||||
if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) < 0)
|
||||
return;
|
||||
if (fstat(fd, &buf) == 0) {
|
||||
(void) strncpy(ut.ut_line, line, sizeof(ut.ut_line));
|
||||
(void) strncpy(ut.ut_name, name, sizeof(ut.ut_name));
|
||||
(void) strncpy(ut.ut_host, host, sizeof(ut.ut_host));
|
||||
(void) time(&ut.ut_time);
|
||||
if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
|
||||
sizeof(struct utmp))
|
||||
(void) ftruncate(fd, buf.st_size);
|
||||
}
|
||||
(void) close(fd);
|
||||
void
|
||||
logwtmp (const char *line, const char *name, const char *host)
|
||||
{
|
||||
struct utmp_data data;
|
||||
struct utmp ut;
|
||||
|
||||
/* Tell that we want to use the UTMP file. */
|
||||
if (utmpname (_PATH_WTMP) == 0)
|
||||
return;
|
||||
|
||||
/* Open UTMP file. */
|
||||
setutent_r (&data);
|
||||
|
||||
/* Position at end of file. */
|
||||
data.loc_utmp = lseek (data.ut_fd, 0, SEEK_END);
|
||||
if (data.loc_utmp == -1)
|
||||
return;
|
||||
|
||||
/* Set information in new entry. */
|
||||
bzero (&ut, sizeof (ut));
|
||||
#if _HAVE_UT_TYPE - 0
|
||||
ut.ut_type = USER_PROCESS;
|
||||
#endif
|
||||
strncpy (ut.ut_line, line, UT_LINESIZE);
|
||||
strncpy (ut.ut_name, name, UT_NAMESIZE);
|
||||
strncpy (ut.ut_host, host, UT_HOSTSIZE);
|
||||
|
||||
#if _HAVE_UT_TV - 0
|
||||
gettimeofday (&ut.ut_tv, NULL);
|
||||
#else
|
||||
time (&ut.ut_time);
|
||||
#endif
|
||||
|
||||
/* Write the entry. */
|
||||
pututline_r (&ut, &data);
|
||||
|
||||
/* Close UTMP file. */
|
||||
endutent_r (&data);
|
||||
|
||||
}
|
||||
|
@ -26,9 +26,29 @@ Boston, MA 02111-1307, USA. */
|
||||
#include <sys/file.h>
|
||||
|
||||
|
||||
/* XXX An alternative solution would be to call a SUID root program
|
||||
which write the new value. */
|
||||
|
||||
int
|
||||
pututline_r (const struct utmp *utmp_ptr, struct utmp_data *utmp_data)
|
||||
{
|
||||
struct stat st;
|
||||
int result = 0;
|
||||
|
||||
#if _HAVE_UT_TYPE - 0
|
||||
/* Test whether ID has any of the legal types because we have to
|
||||
prevent illegal entries. */
|
||||
if (id->ut_type != RUN_LVL && id->ut_type != BOOT_TIME
|
||||
&& id->ut_type != OLD_TIME && id->ut_type != NEW_TIME
|
||||
&& id->ut_type != INIT_PROCESS && id->ut_type != LOGIN_PROCESS
|
||||
&& id->ut_type != USER_PROCESS && id->ut_type != DEAD_PROCESS)
|
||||
/* No, using '<' and '>' for the test is not possible. */
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Open utmp file if not already done. */
|
||||
if (utmp_data->ut_fd == -1)
|
||||
{
|
||||
@ -37,12 +57,14 @@ pututline_r (const struct utmp *utmp_ptr, struct utmp_data *utmp_data)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if _HAVE_UT_TYPE - 0
|
||||
/* Seek position to write. */
|
||||
if (utmp_data->ubuf.ut_type != utmp_ptr->ut_type)
|
||||
{
|
||||
/* We must not overwrite the data in UTMP_DATA. */
|
||||
struct utmp_data *data_tmp = alloca (sizeof (utmp_data));
|
||||
struct utmp *dummy;
|
||||
off_t new_pos;
|
||||
|
||||
*data_tmp = *utmp_data;
|
||||
utmp_data = data_tmp;
|
||||
@ -50,23 +72,25 @@ pututline_r (const struct utmp *utmp_ptr, struct utmp_data *utmp_data)
|
||||
if (getutid_r (utmp_ptr, &dummy, utmp_data) < 0)
|
||||
{
|
||||
if (errno != ESRCH)
|
||||
/* Some error occured. If no entry was found, the position
|
||||
pointer now is at the end of the file. */
|
||||
return -1;
|
||||
|
||||
utmp_data->loc_utmp = lseek (utmp_data->ut_fd, 0, SEEK_END);
|
||||
if (utmp_data->loc_utmp == -1)
|
||||
return -1;
|
||||
}
|
||||
/* Set position pointer to position after adding of the record. */
|
||||
utmp_data->loc_utmp += sizeof (struct utmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Find out how large the file is. */
|
||||
if (fstat (utmp_data->ut_fd, &st) < 0)
|
||||
return -1;
|
||||
|
||||
/* Position file correctly. */
|
||||
if (utmp_data->loc_utmp > 0
|
||||
if (utmp_data->loc_utmp <= st.st_size
|
||||
&& lseek (utmp_data->ut_fd, utmp_data->loc_utmp - sizeof (struct utmp),
|
||||
SEEK_SET) < 0)
|
||||
return -1;
|
||||
|
||||
/* XXX An alternative solution would be to call an SUID root program
|
||||
which write the new value. */
|
||||
|
||||
/* Try to lock the file. */
|
||||
if (flock (utmp_data->ut_fd, LOCK_EX | LOCK_NB) < 0 && errno != ENOSYS)
|
||||
{
|
||||
@ -78,12 +102,22 @@ pututline_r (const struct utmp *utmp_ptr, struct utmp_data *utmp_data)
|
||||
}
|
||||
|
||||
/* Write the new data. */
|
||||
if (write (utmp_data->ut_fd, &utmp_data->ubuf, sizeof (struct utmp))
|
||||
if (write (utmp_data->ut_fd, utmp_ptr, sizeof (struct utmp))
|
||||
!= sizeof (struct utmp))
|
||||
return -1;
|
||||
{
|
||||
/* If we appended a new record this is only partially written.
|
||||
Remove it. */
|
||||
if (utmp_data->loc_utmp > st.st_size)
|
||||
{
|
||||
(void) ftruncate (utmp_data->ut_fd, st.st_size);
|
||||
utmp_data->loc_utmp = st.st_size;
|
||||
}
|
||||
|
||||
result = -1;
|
||||
}
|
||||
|
||||
/* And unlock the file. */
|
||||
(void) flock (utmp_data->ut_fd, LOCK_UN);
|
||||
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
@ -52,7 +52,9 @@ setutent_r (struct utmp_data *utmp_data)
|
||||
|
||||
/* Remember we are at beginning of file. */
|
||||
utmp_data->loc_utmp = 0;
|
||||
utmp_data->ubuf.ut_type = -1;
|
||||
#if _HAVE_UT_TYPE - 0
|
||||
utmp_data->ubuf.ut_type = UT_UNKNOWN;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,9 +70,9 @@ typedef struct
|
||||
#define EXIT_SUCCESS 0 /* Successful exit status. */
|
||||
|
||||
|
||||
/* Maximum length of a multibyte character in the current locale.
|
||||
This is just one until the fancy locale support is finished. */
|
||||
#define MB_CUR_MAX 1
|
||||
/* Maximum length of a multibyte character in the current locale. */
|
||||
#define MB_CUR_MAX (__ctype_get_mb_cur_max ())
|
||||
extern int __ctype_get_mb_cur_max __P ((void));
|
||||
|
||||
|
||||
/* Convert a string to a floating-point number. */
|
||||
|
@ -136,10 +136,8 @@ extern int errno;
|
||||
# define INTERNAL(x) INTERNAL1(x)
|
||||
# define INTERNAL1(x) __##x##_internal
|
||||
# define WEAKNAME(x) WEAKNAME1(x)
|
||||
# define WEAKNAME1(x) __##x
|
||||
#else
|
||||
# define INTERNAL(x) __/**/x/**/_internal
|
||||
# define WEAKNAME(x) __/**/x
|
||||
#endif
|
||||
|
||||
#ifdef USE_NUMBER_GROUPING
|
||||
@ -322,7 +320,7 @@ INTERNAL (strtol) (nptr, endptr, base, group)
|
||||
|
||||
noconv:
|
||||
/* We must handle a special case here: the base is 0 or 16 and the
|
||||
first two characters and '0' and 'x', but the rest are no
|
||||
first two characters are '0' and 'x', but the rest are no
|
||||
hexadecimal digits. This is no error case. We return 0 and
|
||||
ENDPTR points to the `x`. */
|
||||
if (endptr != NULL)
|
||||
@ -337,24 +335,18 @@ noconv:
|
||||
}
|
||||
|
||||
/* External user entry point. */
|
||||
|
||||
/* Prototype. */
|
||||
INT WEAKNAME (strtol) __P ((const STRING_TYPE *nptr, STRING_TYPE **endptr,
|
||||
int base));
|
||||
|
||||
|
||||
INT
|
||||
WEAKNAME (strtol) (nptr, endptr, base)
|
||||
strtol (nptr, endptr, base)
|
||||
const STRING_TYPE *nptr;
|
||||
STRING_TYPE **endptr;
|
||||
int base;
|
||||
{
|
||||
return INTERNAL (strtol) (nptr, endptr, base, 0);
|
||||
}
|
||||
|
||||
#ifdef weak_alias
|
||||
/* We need this indirection when `strtol' is defined as a macro
|
||||
for one of the other names. */
|
||||
#define weak1(x, y) weak_alias (x, y)
|
||||
weak1 (WEAKNAME (strtol), strtol)
|
||||
#ifdef weak_symbol
|
||||
/* We need to weaken this symbol because some the the defined
|
||||
functions do not come from ANSI. The indirection is necessary
|
||||
because `strtol' might be a macro. */
|
||||
#define weak_this(x) weak_symbol (x)
|
||||
weak_this (strtol)
|
||||
#endif
|
||||
|
@ -1,73 +0,0 @@
|
||||
/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static char *olds = NULL;
|
||||
|
||||
/* Parse S into tokens separated by characters in DELIM.
|
||||
If S is NULL, the last string strtok() was called with is
|
||||
used. For example:
|
||||
char s[] = "-abc-=-def";
|
||||
x = strtok(s, "-"); // x = "abc"
|
||||
x = strtok(NULL, "-="); // x = "def"
|
||||
x = strtok(NULL, "="); // x = NULL
|
||||
// s = "abc\0-def\0"
|
||||
*/
|
||||
char *
|
||||
strtok (s, delim)
|
||||
char *s;
|
||||
const char *delim;
|
||||
{
|
||||
char *token;
|
||||
|
||||
if (s == NULL)
|
||||
{
|
||||
if (olds == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
s = olds;
|
||||
}
|
||||
|
||||
/* Scan leading delimiters. */
|
||||
s += strspn (s, delim);
|
||||
if (*s == '\0')
|
||||
{
|
||||
olds = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the end of the token. */
|
||||
token = s;
|
||||
s = strpbrk (token, delim);
|
||||
if (s == NULL)
|
||||
/* This token finishes the string. */
|
||||
olds = NULL;
|
||||
else
|
||||
{
|
||||
/* Terminate the token and make OLDS point past it. */
|
||||
*s = '\0';
|
||||
olds = s + 1;
|
||||
}
|
||||
return token;
|
||||
}
|
@ -77,7 +77,12 @@ struct utmp
|
||||
|
||||
#define ut_time ut_tv.tv_sec /* Backwards compatibility. */
|
||||
|
||||
/* Tell the user that we have a modern system with UT_TYPE, UT_ID
|
||||
and UT_TV fields. */
|
||||
#define _HAVE_UT_TYPE 1
|
||||
#define _HAVE_UT_ID 1
|
||||
#define _HAVE_UT_TV 1
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_UTMP_H_ */
|
||||
|
||||
|
@ -10,14 +10,26 @@ RCSID("$NetBSD: e_exp.S,v 1.4 1995/05/08 23:47:04 jtc Exp $")
|
||||
/* e^x = 2^(x * log2(e)) */
|
||||
ENTRY(__ieee754_exp)
|
||||
fldl 4(%esp)
|
||||
fxam
|
||||
fstsw %ax
|
||||
sahf
|
||||
jnc .LnoInf
|
||||
jp .LisInf
|
||||
.LnoInf:
|
||||
fldl2e
|
||||
fmulp /* x * log2(e) */
|
||||
fstl %st(1)
|
||||
frndint /* int(x * log2(e)) */
|
||||
fstl %st(2)
|
||||
fsubrp /* fract(x * log2(e)) */
|
||||
f2xm1 /* 2^(fract(x * log2(e))) - 1 */
|
||||
f2xm1 /* 2^(fract(x * log2(e))) - 1 */
|
||||
fld1
|
||||
faddp /* 2^(fract(x * log2(e))) */
|
||||
fscale /* e^x */
|
||||
ret
|
||||
|
||||
.LisInf:
|
||||
andb $2, %ah
|
||||
jz .LpInf
|
||||
fldz
|
||||
.LpInf: ret
|
||||
|
Loading…
Reference in New Issue
Block a user