diff options
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/ChangeLog | 6 | ||||
-rw-r--r-- | winsup/Makefile.common | 6 | ||||
-rw-r--r-- | winsup/cygwin/ChangeLog | 47 | ||||
-rw-r--r-- | winsup/cygwin/Makefile.in | 11 | ||||
-rw-r--r-- | winsup/cygwin/cxx.cc | 54 | ||||
-rwxr-xr-x | winsup/cygwin/cygwin-cxx.h | 37 | ||||
-rw-r--r-- | winsup/cygwin/cygwin.din | 8 | ||||
-rw-r--r-- | winsup/cygwin/globals.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/version.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/include/sys/cygwin.h | 7 | ||||
-rw-r--r-- | winsup/cygwin/lib/_cygwin_crt0_common.cc | 73 | ||||
-rwxr-xr-x | winsup/cygwin/libstdcxx_wrapper.cc | 90 | ||||
-rw-r--r-- | winsup/cygwin/winsup.h | 3 |
13 files changed, 323 insertions, 24 deletions
diff --git a/winsup/ChangeLog b/winsup/ChangeLog index 90322944f..94258bec2 100644 --- a/winsup/ChangeLog +++ b/winsup/ChangeLog @@ -1,3 +1,9 @@ +2009-07-07 Dave Korn <dave.korn.cygwin@gmail.com> + + * Makefile.common (COMPILE_CXX): Add support for per-file overrides + to exclude $(nostdinc) and $(nostdincxx) from compiler flags. + (COMPILE_CC): Likewise for $(nostdinc). + 2009-02-23 Sjors Gielen <mailinglist@dazjorz.com> * Makefile.in: Add DESTDIR functionality. diff --git a/winsup/Makefile.common b/winsup/Makefile.common index 96e58ef2d..3ebca3397 100644 --- a/winsup/Makefile.common +++ b/winsup/Makefile.common @@ -130,9 +130,9 @@ ifeq (,${findstring $(gcc_libdir),$(CFLAGS) $(CXXFLAGS) $(CXX) $(CC)}) GCC_INCLUDE:=${subst //,/,-I$(gcc_libdir)/include} endif -COMPILE_CXX=$(CXX) $c $(nostdincxx) $(nostdinc) $(ALL_CXXFLAGS) $(GCC_INCLUDE) \ - -fno-rtti -fno-exceptions -COMPILE_CC=$(CC) $c $(nostdinc) $(ALL_CFLAGS) $(GCC_INCLUDE) +COMPILE_CXX=$(CXX) $c $(if $($(*F)_STDINCFLAGS),,$(nostdincxx) $(nostdinc)) \ + $(ALL_CXXFLAGS) $(GCC_INCLUDE) -fno-rtti -fno-exceptions +COMPILE_CC=$(CC) $c $(if $($(*F)_STDINCFLAGS),,$(nostdinc)) $(ALL_CFLAGS) $(GCC_INCLUDE) vpath %.a $(cygwin_build):$(w32api_lib):$(newlib_build)/libc:$(newlib_build)/libm diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 821196361..b8a823908 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,50 @@ +2009-07-07 Dave Korn <dave.korn.cygwin@gmail.com> + + * Makefile.in (DLL_OFILES): Add libstdcxx_wrapper.o + (libstdcxx_wrapper_CFLAGS): Add flags for new module. + (_cygwin_crt0_common_STDINCFLAGS): Define per-file override. + (libstdcxx_wrapper_STDINCFLAGS, cxx_STDINCFLAGS): Likewise. + * cxx.cc: Include "cygwin-cxx.h". + (operator new): Tweak prototype for full standards compliance. + (operator new[]): Likewise. + (operator new (nothrow)): New fallback function. + (operator new[] (nothrow), operator delete (nothrow), + operator delete[] (nothrow)): Likewise. + (default_cygwin_cxx_malloc): New struct of pointers to the above, + for final last-resort fallback default. + * cygwin-cxx.h: New file. + (struct per_process_cxx_malloc): Define. + (default_cygwin_cxx_malloc): Declare extern. + * cygwin.din (__wrap__ZdaPv): Export new wrapper. + (__wrap__ZdaPvRKSt9nothrow_t, __wrap__ZdlPv, + __wrap__ZdlPvRKSt9nothrow_t, __wrap__Znaj, + __wrap__ZnajRKSt9nothrow_t, __wrap__Znwj, + __wrap__ZnwjRKSt9nothrow_t): Likewise. + * globals.cc (__cygwin_user_data): Init newly-repurposed 'forkee' + field (now 'cxx_malloc') to point to default_cygwin_cxx_malloc. + * libstdcxx_wrapper.cc: New file. + (__wrap__ZdaPv, __wrap__ZdaPvRKSt9nothrow_t, __wrap__ZdlPv, + __wrap__ZdlPvRKSt9nothrow_t, __wrap__Znaj, + __wrap__ZnajRKSt9nothrow_t, __wrap__Znwj, + __wrap__ZnwjRKSt9nothrow_t): Define wrapper functions for libstdc++ + malloc operators and their overrides. + * winsup.h (default_cygwin_cxx_malloc): Declare extern. + * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump. + * include/sys/cygwin.h (struct per_process_cxx_malloc): Forward + declare here. + (struct per_process::forkee): Rename and repurpose from this ... + (struct per_process::cxx_malloc): ... to this. + * lib/_cygwin_crt0_common.cc: Include cygwin-cxx.h. + (WEAK): Define shorthand helper macro. + (__cygwin_cxx_malloc): Define and populate with weak references + to whatever libstdc++ malloc operators will be visible at final + link time for Cygwin apps and dlls. + (_cygwin_crt0_common): Always look up cygwin DLL's internal + per_process data, and don't test for (impossible) failure. Inherit + any members of __cygwin_cxx_malloc that we don't have overrides + for from the DLL's default and store the resulting overall set of + overrides back into the DLL's global per_process data. + 2009-07-07 Corinna Vinschen <corinna@vinschen.de> * cygtls.cc (_cygtls::remove): Fix typo. diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index bac721e69..306166cc9 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -145,9 +145,9 @@ DLL_OFILES:=assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o cygthread.o \ fhandler_termios.o fhandler_tty.o fhandler_virtual.o fhandler_windows.o \ fhandler_zero.o flock.o fnmatch.o fork.o fts.o ftw.o getopt.o glob.o \ glob_pattern_p.o globals.o grp.o heap.o hookapi.o inet_addr.o inet_network.o \ - init.o ioctl.o ipc.o kernel32.o localtime.o lsearch.o malloc_wrapper.o \ - minires-os-if.o minires.o miscfuncs.o mktemp.o mmap.o msg.o mount.o \ - net.o netdb.o nfs.o nftw.o ntea.o passwd.o path.o pinfo.o pipe.o \ + init.o ioctl.o ipc.o kernel32.o libstdcxx_wrapper.o localtime.o lsearch.o \ + malloc_wrapper.o minires-os-if.o minires.o miscfuncs.o mktemp.o mmap.o msg.o \ + mount.o net.o netdb.o nfs.o nftw.o ntea.o passwd.o path.o pinfo.o pipe.o \ poll.o posix_ipc.o pthread.o random.o regcomp.o regerror.o regexec.o \ regfree.o registry.o resource.o rexec.o rcmd.o scandir.o sched.o \ sec_acl.o sec_auth.o sec_helper.o security.o select.o sem.o \ @@ -268,6 +268,7 @@ fhandler_windows_CFLAGS:=-fomit-frame-pointer fhandler_zero_CFLAGS:=-fomit-frame-pointer flock_CFLAGS:=-fomit-frame-pointer grp_CFLAGS:=-fomit-frame-pointer +libstdcxx_wrapper_CFLAGS:=-fomit-frame-pointer malloc_CFLAGS:=-fomit-frame-pointer malloc_wrapper_CFLAGS:=-fomit-frame-pointer miscfuncs_CFLAGS:=-fomit-frame-pointer @@ -285,6 +286,10 @@ sysconf_CFLAGS:=-fomit-frame-pointer uinfo_CFLAGS:=-fomit-frame-pointer endif +_cygwin_crt0_common_STDINCFLAGS:=yes +libstdcxx_wrapper_STDINCFLAGS:=yes +cxx_STDINCFLAGS:=yes + .PHONY: all force dll_ofiles install all_target install_target all_host install_host \ install install-libs install-headers diff --git a/winsup/cygwin/cxx.cc b/winsup/cygwin/cxx.cc index 6021b4fa8..63262f59e 100644 --- a/winsup/cygwin/cxx.cc +++ b/winsup/cygwin/cxx.cc @@ -11,9 +11,14 @@ details. */ #if (__GNUC__ >= 3) #include "winsup.h" +#include "cygwin-cxx.h" + +/* These implementations of operators new and delete are used internally by + the DLL, and are kept separate from the user's/libstdc++'s versions by + use of LD's --wrap option. */ void * -operator new (size_t s) +operator new (std::size_t s) { void *p = calloc (1, s); return p; @@ -26,7 +31,7 @@ operator delete (void *p) } void * -operator new[] (size_t s) +operator new[] (std::size_t s) { return ::operator new (s); } @@ -37,6 +42,34 @@ operator delete[] (void *p) ::operator delete (p); } +/* Nothrow versions, provided only for completeness in the fallback array. */ + +void * +operator new (std::size_t s, const std::nothrow_t &) +{ + void *p = calloc (1, s); + return p; +} + +void +operator delete (void *p, const std::nothrow_t &) +{ + free (p); +} + +void * +operator new[] (std::size_t s, const std::nothrow_t &nt) +{ + return ::operator new (s, nt); +} + +void +operator delete[] (void *p, const std::nothrow_t &nt) +{ + ::operator delete (p, nt); +} + + extern "C" void __cxa_pure_virtual (void) { @@ -52,4 +85,21 @@ extern "C" void __cxa_guard_release () { } + +/* These routines are made available as last-resort fallbacks + for the application. Should not be used in practice. */ + +struct per_process_cxx_malloc default_cygwin_cxx_malloc = +{ + &(operator new), + &(operator new[]), + &(operator delete), + &(operator delete[]), + &(operator new), + &(operator new[]), + &(operator delete), + &(operator delete[]), +}; + + #endif diff --git a/winsup/cygwin/cygwin-cxx.h b/winsup/cygwin/cygwin-cxx.h new file mode 100755 index 000000000..b0eb8c25c --- /dev/null +++ b/winsup/cygwin/cygwin-cxx.h @@ -0,0 +1,37 @@ +/* cygwin-cxx.h + + Copyright 2009 Red Hat, Inc. + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#ifndef _CYGWIN_CXX_H +#define _CYGWIN_CXX_H + +#ifndef __cplusplus +#error This header should not be included by C source files. +#endif + +/* Files including this header must override -nostdinc++ */ +#include <new> + +/* This is an optional struct pointed to by per_process if it exists. */ +struct per_process_cxx_malloc +{ + void *(*oper_new) (std::size_t); + void *(*oper_new__) (std::size_t); + void (*oper_delete) (void *); + void (*oper_delete__) (void *); + void *(*oper_new_nt) (std::size_t, const std::nothrow_t &); + void *(*oper_new___nt) (std::size_t, const std::nothrow_t &); + void (*oper_delete_nt) (void *, const std::nothrow_t &); + void (*oper_delete___nt) (void *, const std::nothrow_t &); +}; + +/* Defined in cxx.cc */ +extern struct per_process_cxx_malloc default_cygwin_cxx_malloc; + +#endif /* _CYGWIN_CXX_H */ diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index 7018ecdb1..52cd362c2 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -1808,3 +1808,11 @@ y1 NOSIGFE y1f NOSIGFE yn NOSIGFE ynf NOSIGFE +__wrap__ZdaPv NOSIGFE # void operator delete[](void *p) throw() +__wrap__ZdaPvRKSt9nothrow_t NOSIGFE # void operator delete[](void *p, const std::nothrow_t &nt) throw() +__wrap__ZdlPv NOSIGFE # void operator delete(void *p) throw() +__wrap__ZdlPvRKSt9nothrow_t NOSIGFE # void operator delete(void *p, const std::nothrow_t &nt) throw() +__wrap__Znaj NOSIGFE # void *operator new[](std::size_t sz) throw (std::bad_alloc) +__wrap__ZnajRKSt9nothrow_t NOSIGFE # void *operator new[](std::size_t sz, const std::nothrow_t &nt) throw() +__wrap__Znwj NOSIGFE # void *operator new(std::size_t sz) throw (std::bad_alloc) +__wrap__ZnwjRKSt9nothrow_t NOSIGFE # void *operator new(std::size_t sz, const std::nothrow_t &nt) throw() diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc index 38f6460c3..b7781899e 100644 --- a/winsup/cygwin/globals.cc +++ b/winsup/cygwin/globals.cc @@ -98,7 +98,7 @@ extern "C" /* premain */ {NULL, NULL, NULL, NULL}, /* run_ctors_p */ 0, /* unused */ {0, 0, 0, 0, 0, 0, 0}, - /* UNUSED forkee */ 0, + /* cxx_malloc */ &default_cygwin_cxx_malloc, /* hmodule */ NULL, /* api_major */ CYGWIN_VERSION_API_MAJOR, /* api_minor */ CYGWIN_VERSION_API_MINOR, diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 32326edc9..cf0a1168b 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -365,12 +365,13 @@ details. */ 209: Export wordexp, wordfree. 210: New ctype layout using variable ctype pointer. Export __ctype_ptr__. 211: Export fpurge, mkstemps. + 212: Add and export libstdc++ malloc wrappers. */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 211 +#define CYGWIN_VERSION_API_MINOR 212 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h index 82a5a162a..3cd3a1c0f 100644 --- a/winsup/cygwin/include/sys/cygwin.h +++ b/winsup/cygwin/include/sys/cygwin.h @@ -194,6 +194,8 @@ enum class MTinterface; #endif +struct per_process_cxx_malloc; + struct per_process { char *initial_sp; @@ -238,9 +240,8 @@ struct per_process DWORD unused[7]; - /* Non-zero means the task was forked. The value is the pid. - Inherited from parent. */ - int forkee; + /* Pointers to real operator new/delete functions for forwarding. */ + struct per_process_cxx_malloc *cxx_malloc; HMODULE hmodule; diff --git a/winsup/cygwin/lib/_cygwin_crt0_common.cc b/winsup/cygwin/lib/_cygwin_crt0_common.cc index a81c3e932..280c50ef4 100644 --- a/winsup/cygwin/lib/_cygwin_crt0_common.cc +++ b/winsup/cygwin/lib/_cygwin_crt0_common.cc @@ -10,8 +10,34 @@ details. */ #include "winsup.h" #include "crt0.h" - -/* Avoid an info message from linker when linking applications. */ +#include "cygwin-cxx.h" + +/* Weaken these declarations so the references don't pull in C++ dependencies + unnecessarily. */ +#define WEAK __attribute__ ((weak)) + +/* Use asm names to bypass the --wrap that is being applied to redirect all other + references to these operators toward the redirectors in the Cygwin DLL; this + way we can record what definitions were visible at final link time but still + send all calls to the redirectors. */ +extern WEAK void *operator new(std::size_t sz) throw (std::bad_alloc) + __asm__ ("___real__Znwj"); +extern WEAK void *operator new[](std::size_t sz) throw (std::bad_alloc) + __asm__ ("___real__Znaj"); +extern WEAK void operator delete(void *p) throw() + __asm__ ("___real__ZdlPv "); +extern WEAK void operator delete[](void *p) throw() + __asm__ ("___real__ZdaPv"); +extern WEAK void *operator new(std::size_t sz, const std::nothrow_t &nt) throw() + __asm__ ("___real__ZnwjRKSt9nothrow_t"); +extern WEAK void *operator new[](std::size_t sz, const std::nothrow_t &nt) throw() + __asm__ ("___real__ZnajRKSt9nothrow_t"); +extern WEAK void operator delete(void *p, const std::nothrow_t &nt) throw() + __asm__ ("___real__ZdlPvRKSt9nothrow_t"); +extern WEAK void operator delete[](void *p, const std::nothrow_t &nt) throw() + __asm__ ("___real__ZdaPvRKSt9nothrow_t"); + +/* Avoid an info message from linker when linking applications. */ extern __declspec(dllimport) struct _reent *_impure_ptr; #undef environ @@ -25,6 +51,14 @@ int main (int, char **, char **); int _fmode; void _pei386_runtime_relocator (); +struct per_process_cxx_malloc __cygwin_cxx_malloc = +{ + &(operator new), &(operator new[]), + &(operator delete), &(operator delete[]), + &(operator new), &(operator new[]), + &(operator delete), &(operator delete[]) +}; + /* Set up pointers to various pieces so the dll can then use them, and then jump to the dll. */ @@ -33,17 +67,15 @@ _cygwin_crt0_common (MainFunc f, per_process *u) { /* This is used to record what the initial sp was. The value is needed when copying the parent's stack to the child during a fork. */ - DWORD newu; + per_process *newu = (per_process *) cygwin_internal (CW_USER_DATA); int uwasnull; if (u != NULL) - uwasnull = 0; /* Caller allocated space for per_process structure */ - else if ((newu = cygwin_internal (CW_USER_DATA)) == (DWORD) -1) - return 0; + uwasnull = 0; /* Caller allocated space for per_process structure. */ else { - u = (per_process *) newu; /* Using DLL built-in per_process */ - uwasnull = 1; /* Remember for later */ + u = newu; /* Using DLL built-in per_process. */ + uwasnull = 1; /* Remember for later. */ } /* The version numbers are the main source of compatibility checking. @@ -64,8 +96,6 @@ _cygwin_crt0_common (MainFunc f, per_process *u) else u->impure_ptr_ptr = &_impure_ptr; /* Older DLLs need this. */ - u->forkee = 0; /* This should only be set in dcrt0.cc - when the process is actually forked */ u->main = f; /* These functions are executed prior to main. They are just stubs unless the @@ -84,7 +114,28 @@ _cygwin_crt0_common (MainFunc f, per_process *u) u->realloc = &realloc; u->calloc = &calloc; - /* Setup the module handle so fork can get the path name. */ + /* Likewise for the C++ memory operators - if any. */ + if (newu && newu->cxx_malloc) + { + /* Inherit what we don't override. */ +#define CONDITIONALLY_OVERRIDE(MEMBER) \ + if (!__cygwin_cxx_malloc.MEMBER) \ + __cygwin_cxx_malloc.MEMBER = newu->cxx_malloc->MEMBER; + CONDITIONALLY_OVERRIDE(oper_new); + CONDITIONALLY_OVERRIDE(oper_new__); + CONDITIONALLY_OVERRIDE(oper_delete); + CONDITIONALLY_OVERRIDE(oper_delete__); + CONDITIONALLY_OVERRIDE(oper_new_nt); + CONDITIONALLY_OVERRIDE(oper_new___nt); + CONDITIONALLY_OVERRIDE(oper_delete_nt); + CONDITIONALLY_OVERRIDE(oper_delete___nt); + } + + /* Now update the resulting set into the global redirectors. */ + if (newu) + newu->cxx_malloc = &__cygwin_cxx_malloc; + + /* Setup the module handle so fork can get the path name. */ u->hmodule = GetModuleHandle (0); /* variables for fork */ diff --git a/winsup/cygwin/libstdcxx_wrapper.cc b/winsup/cygwin/libstdcxx_wrapper.cc new file mode 100755 index 000000000..a0d2f25ee --- /dev/null +++ b/winsup/cygwin/libstdcxx_wrapper.cc @@ -0,0 +1,90 @@ +/* libstdcxx_wrapper.cc + + Copyright 2009 Red Hat, Inc. + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + + +/* We provide these stubs to call into a user's + provided ONDEE replacement if there is one - otherwise + it must fall back to the standard libstdc++ version. */ + +#include "winsup.h" +#include "cygwin-cxx.h" +#include "perprocess.h" + +/* We are declaring asm names for the functions we define here, as we want + to define the wrappers in this file. GCC links everything with wrappers + around the standard C++ memory management operators; these are the wrappers, + but we want the compiler to know they are the malloc operators and not have + it think they're just any old function matching 'extern "C" _wrap_*'. */ + +extern void *operator new(std::size_t sz) throw (std::bad_alloc) + __asm__ ("___wrap__Znwj"); +extern void *operator new[](std::size_t sz) throw (std::bad_alloc) + __asm__ ("___wrap__Znaj"); +extern void operator delete(void *p) throw() + __asm__ ("___wrap__ZdlPv "); +extern void operator delete[](void *p) throw() + __asm__ ("___wrap__ZdaPv"); +extern void *operator new(std::size_t sz, const std::nothrow_t &nt) throw() + __asm__ ("___wrap__ZnwjRKSt9nothrow_t"); +extern void *operator new[](std::size_t sz, const std::nothrow_t &nt) throw() + __asm__ ("___wrap__ZnajRKSt9nothrow_t"); +extern void operator delete(void *p, const std::nothrow_t &nt) throw() + __asm__ ("___wrap__ZdlPvRKSt9nothrow_t"); +extern void operator delete[](void *p, const std::nothrow_t &nt) throw() + __asm__ ("___wrap__ZdaPvRKSt9nothrow_t"); + +extern void * +operator new(std::size_t sz) throw (std::bad_alloc) +{ + return (*user_data->cxx_malloc->oper_new) (sz); +} + +extern void * +operator new[](std::size_t sz) throw (std::bad_alloc) +{ + return (*user_data->cxx_malloc->oper_new__) (sz); +} + +extern void +operator delete(void *p) throw() +{ + (*user_data->cxx_malloc->oper_delete) (p); +} + +extern void +operator delete[](void *p) throw() +{ + (*user_data->cxx_malloc->oper_delete__) (p); +} + +extern void * +operator new(std::size_t sz, const std::nothrow_t &nt) throw() +{ + return (*user_data->cxx_malloc->oper_new_nt) (sz, nt); +} + +extern void * +operator new[](std::size_t sz, const std::nothrow_t &nt) throw() +{ + return (*user_data->cxx_malloc->oper_new___nt) (sz, nt); +} + +extern void +operator delete(void *p, const std::nothrow_t &nt) throw() +{ + (*user_data->cxx_malloc->oper_delete_nt) (p, nt); +} + +extern void +operator delete[](void *p, const std::nothrow_t &nt) throw() +{ + (*user_data->cxx_malloc->oper_delete___nt) (p, nt); +} + diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 5ba9d0c8c..91634dc13 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -183,6 +183,9 @@ extern "C" int dll_dllcrt0 (HMODULE, per_process *); extern "C" int dll_noncygwin_dllcrt0 (HMODULE, per_process *); void __stdcall do_exit (int) __attribute__ ((regparm (1), noreturn)); +/* libstdc++ malloc operator wrapper support. */ +extern struct per_process_cxx_malloc default_cygwin_cxx_malloc; + /* UID/GID */ void uinfo_init (); |