diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-11-24 10:17:24 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-11-24 10:17:24 +0000 |
commit | dfb5fe2dee1b64c57c3df7fc4c0ecb7ad0450730 (patch) | |
tree | cc3db9a916b8d9821f142b97a3200bad61c3975e /docs | |
parent | 1df709beaf6f88e7906d427be4f0c7dcf12e8a55 (diff) |
Move the FAQ. Add a docs dir. Add in a report on thread support.
-Erik
Diffstat (limited to 'docs')
-rw-r--r-- | docs/FAQ.txt | 186 | ||||
-rw-r--r-- | docs/threads.txt | 2275 |
2 files changed, 2461 insertions, 0 deletions
diff --git a/docs/FAQ.txt b/docs/FAQ.txt new file mode 100644 index 000000000..87322174c --- /dev/null +++ b/docs/FAQ.txt @@ -0,0 +1,186 @@ +This is a collection of some of the frequently asked question +about uClibc. Some of the questions even have answers. If you +have additions to this FAQ document, I'd love to add them, + + -Erik + + +Q: What platforms does uClibc run on? + + Currently uClibc runs on arm, i386, m68k, mipsel, powerpc, sh, + sparc, and v850. + + + +Q: Does uClibc support shared libraries? + + Yes. uClibc has shared library support on x86, arm, and powerpc. + Shared Libraries are _not_ currently supported on MMU-less systems. + + + +Q: Why is it called uClibc? + + The letter 'u' is short for the greek letter "mu". "Mu" stands for + "micro", and the "C" is for "controller". uClibc was originaly created to + support uClinux, a port of Linux for MMU-less microcontrollers such as the + Dragonball, Coldfire, and ARM7TDMI. + + + +Q: Can I use it on my desktop x86 system? + + Sure! In fact, this can be very nice during development. By using it on + your development system, you can be sure that the code you are working on + will actually run on your target system. + + + +Q: Why are you doing this? Whats wrong with glibc? + + The inital reason, is that glibc does not support MMU-les systems. But + additionaly, the GNU C library has a different set of goals then uClibc. + The GNU C library is a great piece of software. It complies with just + about every standard ever created, and runs on just about every operating + system as well -- no small task! But there is a price to be paid for that. + It is quite a large library, and keeps getting larger with each release. + It does not even pretend to target embedded systems. To quote from Ulrich + Drepper, the maintainer of GNU libc: "...glibc is not the right thing for + [an embedded OS]. It is designed as a native library (as opposed to + embedded). Many functions (e.g., printf) contain functionality which is + not wanted in embedded systems." 24 May 1999 + + + +Q: So uClibc is smaller then glibc? Doesn't that mean it completely sucks? + How could it be smaller and not suck? + + uClibc has been designed from the ground up to be a C library for embedded + Linux. We don't need to worry about whether we support MS-DOS, or Cygwin, + or any other system. This lets us cut out lots of complexity, and very + carefully optimize for Linux. By very careful design, we can also make a + few shotcuts. For example, glibc contains an implementation of the + wordexp() function, in compliance with the Single Unix Specificaion, + version 2. Well, standards are important. But so is pragmatism. The + wordexp function adds almost 100k to glibc, and yet I am not aware of even + one Linux application that uses wordexp. So uClibc doesn't have wordexp(). + + Glibc is a general purpose C library, and so as policy things are optimized + for speed. uClibc has a large number of routines that have been very + carefuly written to optimize for size instead of speed. + + The end result is a C library that will compile just about everything you + throw at it, thet looks like glibc to application programs when you + compile, and is many times smaller. + + + +Q: Why should I use uClibc? + + I don't know if you should use uClibc or not. It depends on your goals. + If you are building an embedded system, and you are tight on space, then + using uClibc instead if glibc should allow you to use your storage for + other things. + + If you are trying to build a ultra fast fileserver for your company that + has 12 Terabytes of storage, then you probably want to use glibc... + + + +Q: I want to create a closed source commercial application and I want to + protect my intellectual property. If I use uClibc, don't I have to + release my source code? + + No, you do not need to give away your source code just because you use + uClibc and/or run on Linux. + + + +Q: I want to create a closed source commercial application using uClibc. + Is that legal? + + Yes. uClibc is licensed under the LGPL, just like GNU libc. If you are + using uClibc as a shared library, then your closed source application is + 100% legal. Please consider sharing some of the money you make. :-) + + If you are staticly linking your closed source commercial application with + uClibc, then you must take additional steps to comply with the uClibc + license. You can sell your application as usual, but you must also make + your closed source application available to your customers as an object + file which can then be linked with updated versions of uClibc. This will + (in theory) allow your customers to later link with updated versions of + uClibc. You do not need to make the application object file available to + everyone, just to those you gave the fully linked application. + + + +Q: How do I compile stuff? + + The easiest way is to use the compiler wrapper built by uClibc. Instead of + using your usual compiler or cross compiler, you can use i386-uclibc-gcc, + (or whatever is appropriate for your architecture) and it will automagically + make your program link against uClibc. + + + +Q: How do I make autoconf and automake behave? + + First run + export PATH=/usr/i386-linux-uclibc/bin:$PATH + (or similar adjusted for your target architecture) then run you can simply + run autoconf/automake and it should _just work_. + + + +Q: When I run 'ldd' to get a list of the library dependancies for a uClibc + binary, ldd segfault! Or it runs my application? Anyways, it doesn't + work! What should I do? + + Use the ldd that is built by uClibc, not your system's one. When your + system's ldd looks for the library dependancies, it actually tries to + _execute_ that program. This works fine -- usually. I doesn't work at all + when you are cross compiling (thats why ldd segfaults). The ldd program + created by uClibc is cross platform and doesn't actually try to run the + target program like your system one does, so it should do the right thing, + and won't segfault, even when you are cross compiling. + + + +Q: I need you to add <favorite feature> now! How come you don't answer all my + questions on the mailing list withing 5 minutes? I demand that you help me + Right Now! + + You have not paid me a single cent and yet you still have the product of + over year and a half of my work, and lots of work from other people. How + dare you treat me that way! I work on uClibc because I find it + interesting. If you go off flaming me, I will ignore you. + + + +Q: I need you to add <favorite feature>! Are the uClibc developers willing to + be paid in order to add in <favorite feature>? Are you willing to provide + support contracts? + + Sure! Now you have our attention! What you should do is contact + Erik Andersen of CodePoet Consulting to bid on your project. If Erik + is too busy to personally add your feature, there are several other + active contributors who may be able to help you out. + + +Q: I think you guys are great and I want to help support your work! + + Wow, that would be great! You can visit + http://paypal.com/ + click on "Send Money" and donate to andersen@codepoet.org + + + +I hope that was helpful... If you have and comment, corrections, insults, +suggestions, or bribes, email me at andersen@codepoet.org. + + -Erik + +-- +Erik B. Andersen +andersen@codepoet.org +http://codepoet-consulting.com/ diff --git a/docs/threads.txt b/docs/threads.txt new file mode 100644 index 000000000..2d5d9e623 --- /dev/null +++ b/docs/threads.txt @@ -0,0 +1,2275 @@ +uClibc thread-safety analysis +By Steve Thayer <sthayer@coactive.com> +with updates by Erik Andersen <andersee@debian.org> + +Introduction: + +The purpose of this document is to identify the things that need to be done +to the uClibc C library in order to make it thread-safe. The goal is to be +able to use a pthreads thread implementation under uClinux, using the uClibc +C library. To help identify the things that require changing, I used David R. +Butenhof's book Programming With POSIX Threads, the source code for the +glibc 2.1.3 C library, and the source code for the C library included in the +Proventhreads distribution. + +References: + +Butenhof, David R., Programming With POSIX Threads, Addison Wesley Longman, Inc., Reading, MA, ISBN 0-201-63392-2, 1997. + + +The GNU C library is available from the Free Software Foundation +http://www.gnu.org/software/libc/libc.html + +Proventhreads is part of the Inferno Operating system. +http://www.vitanuova.com/inferno/index.html + + +1. Stdio: + +1.1 Buffer access mutexes + + The following functions are required in order to protect shared + I/O buffers from being accessed by more than one thread at a time. + None of these functions are currently implemented in the uClibc + library, so they must be added. + + flockfile <required> <--- + ftrylockfile <required> <--- + funlockfile <required> <--- + +1.2 Functions that must use buffer access mutexes, according to Butenhof + + The following functions are identified by Butenhof as needing to use + buffer access mutexes. This does not represent all functions that + need to use the mutexes. + + getc <mutex required> <--- + getchar <mutex required> <--- + putc <mutex required> <--- + putchar <mutex required> <--- + +1.3 Functions from glibc (libio) that use buffer access mutexes + + The following functions are functions found in glibc that currently + use the buffer access mutexes. Comments in brackets represent + status of uClibc with regard to these functions. Most of these + functions aren't even supported under uClibc, so no work is required. + The rest may require the access mutex. (These must be analyzed on a + case-by-case basis.) + + clearerr <mutex required> <--- + feof <mutex required> <--- + ferror <mutex required> <--- + fputc <mutex required> <--- + fputwc <not supported> + freopen <mutex required> <--- + freopen64 <not supported> + fseek <mutex required> <--- + fseeko <not supported> + fseeko64 <not supported> + ftello <not supported> + ftello64 <not supported> + fwide <not supported> + getc <macro for fgetc> + getchar <macro for fgetc> + getwc <not supported> + getwchar <not supported> + iofclose <not supported> + iofflush <not supported> + iofgetpos <not supported> + iofgetpos64 <not supported> + iofgets <not supported> + iofgetws <not supported> + iofputs <not supported> + iofputws <not supported> + iofread <not supported> + iofsetpos <not supported> + iofsetpos64 <not supported> + ioftell <not supported> + iofwrite <not supported> + iogetdelim <not supported> + iogets <not supported> + ioputs <not supported> + ioseekoff <not supported> + ioseekpos <not supported> + iosetbuffer <not supported> + iosetvbuf <not supported> + ioungetc <not supported> + ioungetwc <not supported> + oldiofclose <not supported> + oldiofgetpos <not supported> + oldiofgetpos64 <not supported> + oldiofsetpos <not supported> + oldiofsetpos64 <not supported> + peekc <not supported> + putc <macro for fputc> + putchar <macro for fputc> + putwc <not supported> + putwchar <not supported> + rewind <mutex required> <--- + +1.4 Functions from Proventhreads that use buffer access mutexes + + See description above. This applies only to the C library included + in the proventhreads distribution. + + clearerr <mutex required> <--- + fclose <mutex required> <--- + fflush <mutex required> <--- + fgetc <mutex required> <--- + __getc <not supported> + fgetline <not supported> + fgetpos <mutex required> <--- + fgets <mutex required> <--- + fpurge <not supported> + fputc <mutex required> <--- + __putc <not supported> + fputs <mutex required> <--- + fread <mutex required> <--- + freopen <mutex required> <--- + fscanf <mutex required> <--- + fseek <mutex required> <--- + ftell <mutex required> <--- + fwalk <not supported> + fwrite <mutex required> <--- + getc <macro for fgetc> + getchar <mutex required> <--- + putc <macro for fputc> + putchar <mutex required> <--- + puts <mutex required> <--- + putw <not supported> + refill <not supported> + rewind <mutex required> <--- + scanf <mutex required> <--- + setvbuf <mutex required> <--- + ungetc <mutex required> <--- + vfprintf <mutex required> <--- + vscanf <mutex required> <--- + +1.5 Unlocked buffer access + + These functions get used in situations where speed is important, + and locking isn't necessary, or for use in a section of code that + is already locked. For example, a for-loop that makes multiple calls + to getc could make an exlicit call to flockfile outside the loop, and + then use getc_unlocked within the loop for speed. That way, the lock + only needs to be grabbed and released once, rather than for each call. + + getc_unlocked <required> <--- + getchar_unlocked <required> <--- + putc_unlocked <required> <--- + putchar_unlocked <required> <--- + +1.6 Additional unlocked calls made in glibc + + These are additional functions (not mentioned by Butenhof) that the + glibc library uses for unlocked buffer access. Though not strictly + necessary, these may be nice to have in uClibc. + + fileno_unlocked <desired> <--- + clearerr_unlocked <desired> <--- + feof_unlocked <desired> <--- + ferror_unlocked <desired> <--- + fputc_unlocked <desired> <--- + fgetc_unlocked <desired> <--- + fflush_unlocked <desired> <--- + fread_unlocked <desired> <--- + fwrite_unlocked <desired> <--- + fgets_unlocked <desired> <--- + fputs_unlocked <desired> <--- + +1.7 Additional unlocked calls made in Proventhreads + + Proventhreads only provides the four unlocked function calls above. + + <none> + + +2. Thread-safe functions: + + There are some functions in the C library standard that are + simply not thread-safe and cannot be thread-safe using their + current interface. For example, any function that returns a + pointer to static data, or requires static context between + calls. To resolve this problem, new functions were added to + the standard that perform the same basic task, but use a new + interface that does not require static data. These functions + share their name with the old unsafe functions, but have an + "_r" appended to the name. By definition, these functions are + reentrant and thread-safe. It is important to note that these + functions to do not depend on <pthread.h> and can be used even + if threading is not supported. + +2.1 User and terminal identification: + + getlogin_r <implemented> + ctermid <implemented> (1) + ttyname_r <required> <--- + + 1. ctermid is a special case. The signature has not changed, but a + requirement has been added that its parameter point to a structure + of exactly L_ctermid bytes. + +2.2 Directory searching + + readdir_r <required> <--- + +2.3 String token + + strtok_r <implemented> + +2.4 Time representation + + asctime_r <implemented> + ctime_r <implemented> + gmtime_r <implemented> + localtime_r <implemented> + +2.5 Random number generation + + rand_r <required> <--- + +2.6 Group and user database + + getgrgid_r <required> <--- + getgrnam_r <required> <--- + getpwuid_r <implemented> + getpwnam_r <implemented> + +2.7 Additional thread-safe functions implemented by glibc + + The following is a list of additional functions implemented by glibc + that also provide thread-safe functionality. Most of these functions + are not supported by uClibc, so there is no need to implement the + thread-safe version. Those that do apply, but have not been + implemented yet are highlighted. + + __fgetpwent_r <not supported> + fgetpwent_r <implemented> + __ttyname_r <not supported> + getttyname_r <not supported> + __getmntent_r <not supported> + getmntent_r <desired> <--- + ecvt_r <not supported> + fcvt_r <not supported> + qecvt_r <not supported> + qfcvt_r <not supported> + hcreate_r <not supported> + hdestroy_r <not supported> + hsearch_r <not supported> + __getspent_r <not supported> + getspent_r <not supported> + __getspnam_r <not supported> + getspnam_r <not supported> + __sgetspent_r <not supported> + sgetspent_r <not supported> + __fgetspent_r <not supported> + fgetspent_r <not supported> + __gethostbyaddr_r <not supported> + gethostbyaddr_r <desired> <--- + __gethostbyname2_r <not supported> + gethostbyname2_r <not supported> + __gethostbyname_r <not supported> + gethostbyname_r <desired> <--- + __gethostent_r <not supported + gethostent_r <not supported> + __getnetbyaddr_r <not supported> + getnetbyaddr_r <desired> <--- + __getnetent_r <not supported> + getnetent_r <desired> <--- + __getnetbyname_r <not supported> + getnetbyname_r <desired> <--- + __getprotobynumber_r <not supported> + getprotobynumber_r <desired> <--- + __getprotoent_r <not supported> + getprotoent_r <desired> <--- + __getprotobyname_r <not supported> + getprotobyname_r <desired> <--- + __getservbyname_r <not supported> + getservbyname_r <desired> <--- + __getservbyport_r <not supported> + getservbyport_r <desired> <--- + __getservent_r <not supported> + getservent_r <desired> <--- + __getrpcent_r <not supported> + getrpcent_r <desired> <--- + __getrpcbyname_r <not supported> + getrpcbyname_r <desired> <--- + __getrpcbynumber_r <not supported> + getrpcbynumber_r <desired> <--- + ether_aton_r <not supported> + ether_ntoa_r <not supported> + __getnetgrent_r <not supported> + __internal_getnetgrent_r <not supported> + getnetgrent_r <not supported> + __getaliasent_r <not supported> + getaliasent_r <not supported> + __getaliasbyname_r <not supported> + getaliasbyname_r <not supported> + __nscd_getpwnam_r <not supported> + __nscd_getpwuid_r <not supported> + nscd_getpw_r <not supported> + __nscd_getgrgid_r <not supported> + __nscd_getgrnam_r <not supported> + nscd_getgr_r <not supported> + __nscd_gethostbyaddr_r <not supported> + __nscd_gethostbyname2_r <not supported> + __nscd_gethostbyname_r <not supported> + nscd_gethst_r <not supported> + __getutent_r <desired> <--- + getutent_r <desired> <--- + getutent_r_unknown <not supported> + getutid_r_unknown <not supported> + getutline_r_unknown <not supported> + __getutid_r <not supported> + getutid_r <desired> <--- + __getutline_r <not supported> + getutline_r <required> <--- + getutent_r_file <not supported> + getutid_r_file <not supported> + getutline_r_file <not supported> + internal_getut_r <not supported> + getutent_r_daemon <not supported> + getutid_r_daemon <not supported> + getutline_r_daemon <not supported> + __ptsname_r <not supported> + ptsname_r <not supported> + + +2.8 Additional thread-safe functions implemented by Proventhreads + + See description above. This applies only to the C library included + in the proventhreads distribution. + + inet_ntoa_r <desired> <--- + gethostbyaddr_r <desired> <--- + gethostbyname_r <desired> <--- + gethostent_r <not supported> + getnetbyaddr_r <desired> <--- + getnetbyname_r <desired> <--- + getnetent_r <desired> <--- + getprotobynumber_r <desired> <--- + getprotoent_r <desired> <--- + getprotobyname_r <desired> <--- + getservbyname_r <desired> <--- + getservbyport_r <desired> <--- + getservent_r <desired> <--- + + +3. List of functions in uClibc that use static data structures + + The following is a list of static data structures found in uClibc, + and the functions that use them. In most cases, static data is not + thread-safe, since multiple threads can access the same data at the + same time. This is an attempt to identify all of the static data that + is not considered thread-safe. Some of these problems will get + resolved by the changes outlines above. + + crypt/crypt.c: + + static struct crypt_data __crypt_data; + + crypt <crypt_r implemented> + setkey <setkey_r implemented> + encrypt <encrypt_r implemented> + + -------------------------------------------------------------------- + + crypt/md5.c: + + static unsigned char PADDING[64] <fix desired> <--- + + NOTE: This is okay, but should use the const keyword. + + -------------------------------------------------------------------- + + inet/addr.c: + + static char buf[16]; + + inet_ntoa <inet_ntoa_r not implemented> <--- + + -------------------------------------------------------------------- + + inet/getnetent.c: + + static FILE *netf = NULL; + static char line[BUFSIZ+1]; + static struct netent net; + static char *net_aliases[MAXALIASES]; + + setnetent <fix required> <--- + endnetent <fix required> <--- + getnetent <getnetent_r required> <--- + + NOTE: setnetent and endnetent are not implemented in glibc. + Proventhreads uses pthread mutexes to protect this static data. + + -------------------------------------------------------------------- + + inet/getproto.c: + + static FILE *protof = NULL; + static char line[BUFSIZ+1]; + static struct protoent proto; + static char *proto_aliases[MAXALIASES]; + static int proto_stayopen; + + setprotoent <fix required> <--- + endprotoent <fix required> <--- + getprotoent <getprotoent_r required> <--- + getprotobyname <getprotobyname_r required> <--- + getprotobynumber <getprotobynumber required> <--- + + NOTE: setprotoent and endprotoent are not implemented in glibc. + Proventhreads uses pthread mutexes to protect this static data. + + -------------------------------------------------------------------- + + inet/getservice.c: + + static FILE *servf = NULL; + static char line[BUFSIZ+1]; + static struct servent serv; + static char *serv_aliases[MAXALIASES]; + static int serv_stayopen; + + setservent <fix required> <--- + endservent <fix required> <--- + getservent <getservent_r required> <--- + getservbyname <getservbyname_r required> <--- + getservbyport <getservbyport_r required> <--- + + NOTE: setservent and endservent are not implemented in glibc. + Proventhreads uses pthread mutexes to protect this static data. + + -------------------------------------------------------------------- + + net/resolv.c: + + static int id = 1; + static int ns = 0; + + dns_lookup <fix required> <--- + + NOTE: dns_lookup is not implemented by glibc or Proventhreads. + + static struct hostent h; + static char namebuf[256]; + static struct in_addr in; + static struct in_addr *addr_list[2]; + + gethostbyname <gethostbyname_r required> <--- + + static struct hostent h; + static char namebuf[256]; + static struct in_addr in; + static struct in_addr *addr_list[2]; + + gethostbyaddr <gethostbyaddr_r required> <--- + + static struct hostent h; + static struct in_addr in; + static struct in_addr *addr_list[2]; + static char line[80]; + + read_etc_hosts <fix required> <--- + + NOTE: dns_lookup is not implemented by glibc or Proventhreads. + + -------------------------------------------------------------------- + + inet/rpc/auth_none.c: + + static struct auth_ops ops + static struct authnone_private + + authnone_create <fix required> <--- + authnone_marshal <fix required> <--- + + NOTE: This file makes a lot of use of this static variable and + also a global allocated authentication structure. Care should + be taken in fixing this to make it thread-safe. + + -------------------------------------------------------------------- + + inet/rpc/auth_unix.c: + + static struct auth_ops auth_unix_ops + + authunix_create <fix required> <--- + marshal_new_auth <fix required> <--- + + NOTE: This file makes a lot of use of this static variable and + also a global allocated authentication structure. Care should + be taken in fixing this to make it thread-safe. + + -------------------------------------------------------------------- + + inet/rpc/bindresvport.c: + + static short port; + + bindresvport <fix required> <--- + + -------------------------------------------------------------------- + + inet/rpc/clnt_perror.c: + + static char *buf; + static struct rpc_errtab rpc_errlist[] + static struct auth_errtab auth_errlist[] + + NOTE: These static structures all have #if 0 around them, so they + do not get compiled in. Hopefully, we don't have to worry about + them right now, but prehaps a comment should be added to the code + indicating that it is not thread-safe. + + -------------------------------------------------------------------- + + inet/rpc/clnt_raw.c: + + static struct clntraw_private + static struct clnt_ops client_ops + + clntraw_create <fix required> <--- + clntraw_call <fix required> <--- + clntraw_freeres <fix required> <--- + + NOTE: This file makes a lot of use of these static variables and + also a global allocated client structure. Care should + be taken in fixing this to make it thread-safe. + + -------------------------------------------------------------------- + + inet/rpc/clnt_simple.c: + + static struct callrpc_private + + callrpc <fix required> <--- + + -------------------------------------------------------------------- + + inet/rpc/clnt_tcp.c: + + static struct clnt_ops tcp_ops + + clnttcp_create + + NOTE: This static structure is just a group of function pointers. + It could probably be made const, but this might affect the function + signature. This should be investigated further. + + -------------------------------------------------------------------- + + inet/rpc/clnt_udp.c: + + static struct clnt_ops udp_ops + + clntudp_bufcreate + + NOTE: This static structure is just a group of function pointers. + It could probably be made const, but this might affect the function + signature. This should be investigated further. + + -------------------------------------------------------------------- + + inet/rpc/getrpcent.c: + + static char RPCDB[] <fix desired> <--- + + NOTE: This is okay, but should use the const keyword. + + -------------------------------------------------------------------- + + inet/rpc/pmap_clnt.c: + + static struct timeval timeout <fix desired> <--- + static struct timeval tottimeout <fix desired> <--- + + NOTE: These are okay, but should use the const keyword. + + -------------------------------------------------------------------- + + inet/rpc/pmap_getport.c: + + static struct timeval timeout <fix desired> <--- + static struct timeval tottimeout <fix desired> <--- + + NOTE: These are okay, but should use the const keyword. + + -------------------------------------------------------------------- + + inet/rpc/pmap_rmt.c: + + static struct timeval timeout <fix desired> <--- + + NOTE: This is okay, but should use the const keyword. + + -------------------------------------------------------------------- + + inet/rpc/rpc_dtablesize.c: + + static int size; + + _rpc_dtablesize <fix required> <--- + + -------------------------------------------------------------------- + + inet/rpc/rpc_prot.c: + + static struct xdr_discrim reply_dscrm[3] <fix desired> <--- + + NOTE: This is okay, but should use the const keyword. + + -------------------------------------------------------------------- + + inet/rpc/svc.c: + + static SVCXPRT **xports; + static SVCXPRT *xports[NOFILE]; + static struct svc_callout + + xprt_register <fix required> <--- + xprt_unregister <fix required> <--- + svc_getreqset <fix required> <--- + svc_register <fix required> <--- + svc_unregister <fix required> <--- + svc_callout <fix required> <--- + + NOTE: This is intricate code, and care should be taken when making + this thread-safe. + + -------------------------------------------------------------------- + + inet/rpc/svc_auth.c: + + static struct svcauthsw <fix desired> <--- + + NOTE: This is okay, but should use the const keyword. + + -------------------------------------------------------------------- + + net/rpc/svc_raw.c: + + static st |