mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-10-30 10:45:40 +03:00 
			
		
		
		
	calls with constant strings shows a small (~10%) performance gain, strdup is typically used in error reporting code, so not performance critical. Remove the now unused __need_malloc_and_calloc related defines from stdlib.h. Rename existing uses of str(n)dup to __str(n)dup so it no longer needs to be redirected to a builtin. Also building GLIBC with -Os now no longer shows localplt or linkname space failures (partial fix for BZ #15105 and BZ #19463). [BZ #15105] [BZ #19463] * elf/dl-cache.c (_dl_load_cache_lookup): Use __strdup. * inet/rcmd.c (rcmd_af): Likewise. * inet/rexec.c (rexec_af): Likewise. * intl/dcigettext.c (_LIBC): Likewise. * intl/finddomain.c (_nl_find_domain): Use strdup expansion. * locale/loadarchive.c (_nl_load_locale_from_archive): Use __strdup. * locale/setlocale.c (setlocale): Likewise. * posix/spawn_faction_addopen.c (posix_spawn_file_actions_addopen): Likewise. * stdlib/putenv.c (putenv): Use __strndup. * sunrpc/svc_simple.c (__registerrpc): Use __strdup. * sysdeps/posix/getaddrinfo.c (gaih_inet): Use __strdup/__strndup. * include/stdlib.h (__need_malloc_and_calloc): Remove uses. (__Need_M_And_C) Remove define/undef. * stdlib/stdlib.h (__need_malloc_and_calloc): Remove uses. (__malloc_and_calloc_defined): Remove define. * string/bits/string2.h (__strdup): Remove define. (strdup): Likewise. (__strndup): Likewise. (strndup): Likewise.
		
			
				
	
	
		
			187 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * svc_simple.c
 | |
|  * Simplified front end to rpc.
 | |
|  *
 | |
|  * Copyright (c) 2010, Oracle America, Inc.
 | |
|  *
 | |
|  * Redistribution and use in source and binary forms, with or without
 | |
|  * modification, are permitted provided that the following conditions are
 | |
|  * met:
 | |
|  *
 | |
|  *     * Redistributions of source code must retain the above copyright
 | |
|  *       notice, this list of conditions and the following disclaimer.
 | |
|  *     * 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.
 | |
|  *     * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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
 | |
|  *   COPYRIGHT HOLDER 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.
 | |
|  */
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <string.h>
 | |
| #include <libintl.h>
 | |
| #include <unistd.h>
 | |
| #include <rpc/rpc.h>
 | |
| #include <rpc/pmap_clnt.h>
 | |
| #include <sys/socket.h>
 | |
| #include <netdb.h>
 | |
| 
 | |
| #include <wchar.h>
 | |
| #include <libio/iolibio.h>
 | |
| #include <shlib-compat.h>
 | |
| 
 | |
| struct proglst_
 | |
|   {
 | |
|     char *(*p_progname) (char *);
 | |
|     int p_prognum;
 | |
|     int p_procnum;
 | |
|     xdrproc_t p_inproc, p_outproc;
 | |
|     struct proglst_ *p_nxt;
 | |
|   };
 | |
| #ifdef _RPC_THREAD_SAFE_
 | |
| #define proglst RPC_THREAD_VARIABLE(svcsimple_proglst_s)
 | |
| #else
 | |
| static struct proglst_ *proglst;
 | |
| #endif
 | |
| 
 | |
| 
 | |
| static void universal (struct svc_req *rqstp, SVCXPRT *transp_s);
 | |
| #ifdef _RPC_THREAD_SAFE_
 | |
| #define transp RPC_THREAD_VARIABLE(svcsimple_transp_s)
 | |
| #else
 | |
| static SVCXPRT *transp;
 | |
| #endif
 | |
| 
 | |
| int
 | |
| __registerrpc (u_long prognum, u_long versnum, u_long procnum,
 | |
| 	       char *(*progname) (char *), xdrproc_t inproc, xdrproc_t outproc)
 | |
| {
 | |
|   struct proglst_ *pl;
 | |
|   char *buf;
 | |
| 
 | |
|   if (procnum == NULLPROC)
 | |
|     {
 | |
| 
 | |
|       if (__asprintf (&buf, _("can't reassign procedure number %ld\n"),
 | |
| 		      NULLPROC) < 0)
 | |
| 	buf = NULL;
 | |
|       goto err_out;
 | |
|     }
 | |
|   if (transp == 0)
 | |
|     {
 | |
|       transp = svcudp_create (RPC_ANYSOCK);
 | |
|       if (transp == NULL)
 | |
| 	{
 | |
| 	  buf = __strdup (_("couldn't create an rpc server\n"));
 | |
| 	  goto err_out;
 | |
| 	}
 | |
|     }
 | |
|   (void) pmap_unset ((u_long) prognum, (u_long) versnum);
 | |
|   if (!svc_register (transp, (u_long) prognum, (u_long) versnum,
 | |
| 		     universal, IPPROTO_UDP))
 | |
|     {
 | |
|       if (__asprintf (&buf, _("couldn't register prog %ld vers %ld\n"),
 | |
| 		      prognum, versnum) < 0)
 | |
| 	buf = NULL;
 | |
|       goto err_out;
 | |
|     }
 | |
|   pl = (struct proglst_ *) malloc (sizeof (struct proglst_));
 | |
|   if (pl == NULL)
 | |
|     {
 | |
|       buf = __strdup (_("registerrpc: out of memory\n"));
 | |
|       goto err_out;
 | |
|     }
 | |
|   pl->p_progname = progname;
 | |
|   pl->p_prognum = prognum;
 | |
|   pl->p_procnum = procnum;
 | |
|   pl->p_inproc = inproc;
 | |
|   pl->p_outproc = outproc;
 | |
|   pl->p_nxt = proglst;
 | |
|   proglst = pl;
 | |
|   return 0;
 | |
| 
 | |
|  err_out:
 | |
|   if (buf == NULL)
 | |
|     return -1;
 | |
|   (void) __fxprintf (NULL, "%s", buf);
 | |
|   free (buf);
 | |
|   return -1;
 | |
| }
 | |
| 
 | |
| libc_sunrpc_symbol (__registerrpc, registerrpc, GLIBC_2_0)
 | |
| 
 | |
| 
 | |
| static void
 | |
| universal (struct svc_req *rqstp, SVCXPRT *transp_l)
 | |
| {
 | |
|   int prog, proc;
 | |
|   char *outdata;
 | |
|   char xdrbuf[UDPMSGSIZE];
 | |
|   struct proglst_ *pl;
 | |
|   char *buf = NULL;
 | |
| 
 | |
|   /*
 | |
|    * enforce "procnum 0 is echo" convention
 | |
|    */
 | |
|   if (rqstp->rq_proc == NULLPROC)
 | |
|     {
 | |
|       if (svc_sendreply (transp_l, (xdrproc_t)xdr_void,
 | |
| 			 (char *) NULL) == FALSE)
 | |
| 	{
 | |
| 	  __write (STDERR_FILENO, "xxx\n", 4);
 | |
| 	  exit (1);
 | |
| 	}
 | |
|       return;
 | |
|     }
 | |
|   prog = rqstp->rq_prog;
 | |
|   proc = rqstp->rq_proc;
 | |
|   for (pl = proglst; pl != NULL; pl = pl->p_nxt)
 | |
|     if (pl->p_prognum == prog && pl->p_procnum == proc)
 | |
|       {
 | |
| 	/* decode arguments into a CLEAN buffer */
 | |
| 	__bzero (xdrbuf, sizeof (xdrbuf));	/* required ! */
 | |
| 	if (!svc_getargs (transp_l, pl->p_inproc, xdrbuf))
 | |
| 	  {
 | |
| 	    svcerr_decode (transp_l);
 | |
| 	    return;
 | |
| 	  }
 | |
| 	outdata = (*(pl->p_progname)) (xdrbuf);
 | |
| 	if (outdata == NULL && pl->p_outproc != (xdrproc_t)xdr_void)
 | |
| 	  /* there was an error */
 | |
| 	  return;
 | |
| 	if (!svc_sendreply (transp_l, pl->p_outproc, outdata))
 | |
| 	  {
 | |
| 	    if (__asprintf (&buf, _("trouble replying to prog %d\n"),
 | |
| 			    pl->p_prognum) < 0)
 | |
| 	      buf = NULL;
 | |
| 	    goto err_out2;
 | |
| 	  }
 | |
| 	/* free the decoded arguments */
 | |
| 	(void) svc_freeargs (transp_l, pl->p_inproc, xdrbuf);
 | |
| 	return;
 | |
|       }
 | |
|   if (__asprintf (&buf, _("never registered prog %d\n"), prog) < 0)
 | |
|     buf = NULL;
 | |
|  err_out2:
 | |
|   if (buf == NULL)
 | |
|     exit (1);
 | |
|   __fxprintf (NULL, "%s", buf);
 | |
|   free (buf);
 | |
|   exit (1);
 | |
| }
 |