1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2014 Garrett D'Amore <garrett@damore.org>
  25  */
  26 
  27 /*
  28  * Implementation of all external interfaces between ld.so.1 and libc.
  29  *
  30  * This file started as a set of routines that provided synchronization and
  31  * locking operations using calls to libthread.  libthread has merged with libc
  32  * under the Unified Process Model (UPM), and things have gotten a lot simpler.
  33  * This file continues to establish and redirect various events within ld.so.1
  34  * to interfaces within libc.
  35  *
  36  * Until libc is loaded and relocated, any external interfaces are captured
  37  * locally.  Each link-map list maintains its own set of external vectors, as
  38  * each link-map list typically provides its own libc.  Although this per-link-
  39  * map list vectoring provides a degree of flexibility, there is a protocol
  40  * expected when calling various libc interfaces.
  41  *
  42  * i.   Any new alternative link-map list should call CI_THRINIT, and then call
  43  *      CI_TLS_MODADD to register any TLS for each object of that link-map list
  44  *      (this item is labeled i. as auditors can be the first objects loaded,
  45  *      and they exist on their own lik-map list).
  46  *
  47  * ii.  For the primary link-map list, CI_TLS_STATMOD must be called first to
  48  *      register any static TLS.  This routine is called regardless of there
  49  *      being any TLS, as this routine also establishes the link-map list as the
  50  *      primary list and fixes the association of uberdata).  CI_THRINIT should
  51  *      then be called.
  52  *
  53  * iii. Any objects added to an existing link-map list (primary or alternative)
  54  *      should call CI_TLS_MODADD to register any additional TLS.
  55  *
  56  * These events are established by:
  57  *
  58  * i.   Typically, libc is loaded as part of the primary dependencies of any
  59  *      link-map list (since the Unified Process Model (UPM), libc can't be
  60  *      lazily loaded).  To minimize the possibility of loading and registering
  61  *      objects, and then tearing them down (because of a relocation error),
  62  *      external vectors are established as part of load_completion().  This
  63  *      routine is called on completion of any operation that can cause objects
  64  *      to be loaded.  This point of control insures the objects have been fully
  65  *      analyzed and relocated, and moved to their controlling link-map list.
  66  *      The external vectors are established prior to any .inits being fired.
  67  *
  68  * ii.  Calls to CI_THRINIT, and CI_TLS_MODADD also occur as part of
  69  *      load_completion().  CI_THRINIT is only called once for each link-map
  70  *      control list.
  71  *
  72  * iii. Calls to CI_TLS_STATMOD, and CI_THRINIT occur for the primary link-map
  73  *      list in the final stages of setup().
  74  *
  75  * The interfaces provide by libc can be divided into two families.  The first
  76  * family consists of those interfaces that should be called from the link-map
  77  * list.  It's possible that these interfaces convey state concerning the
  78  * link-map list they are part of:
  79  *
  80  *      CI_ATEXIT
  81  *      CI TLS_MODADD
  82  *      CI_TLS_MODREM
  83  *      CI_TLS_STATMOD
  84  *      CI_THRINIT
  85  *
  86  * The second family are global in nature, that is, the link-map list from
  87  * which they are called provides no state information.  In fact, for
  88  * CI_BIND_GUARD, the calling link-map isn't even known.  The link-map can only
  89  * be deduced after ld.so.1's global lock has been obtained.  Therefore, the
  90  * following interfaces are also maintained as global:
  91  *
  92  *      CI_LCMESSAGES
  93  *      CI_BIND_GUARD
  94  *      CI_BIND_CLEAR
  95  *      CI_THR_SELF
  96  *
  97  * Note, it is possible that these global interfaces are obtained from an
  98  * alternative link-map list that gets torn down because of a processing
  99  * failure (unlikely, because the link-map list components must be analyzed
 100  * and relocated prior to load_completion(), but perhaps the tear down is still
 101  * a possibility).  Thus the global interfaces may have to be replaced.  Once
 102  * the interfaces have been obtained from the primary link-map, they can
 103  * remain fixed, as the primary link-map isn't going to go anywhere.
 104  *
 105  * The last wrinkle in the puzzle is what happens if an alternative link-map
 106  * is loaded with no libc dependency?  In this case, the alternative objects
 107  * can not call CI_THRINIT, can not be allowed to use TLS, and will not receive
 108  * any atexit processing.
 109  *
 110  * The history of these external interfaces is defined by their version:
 111  *
 112  * TI_VERSION == 1
 113  *      Under this model libthread provided rw_rwlock/rw_unlock, through which
 114  *      all rt_mutex_lock/rt_mutex_unlock calls were vectored.
 115  *      Under libc/libthread these interfaces provided _sigon/_sigoff (unlike
 116  *      lwp/libthread that provided signal blocking via bind_guard/bind_clear).
 117  *
 118  * TI_VERSION == 2
 119  *      Under this model only libthreads bind_guard/bind_clear and thr_self
 120  *      interfaces were used.  Both libthreads blocked signals under the
 121  *      bind_guard/bind_clear interfaces.   Lower level locking is derived
 122  *      from internally bound _lwp_ interfaces.  This removes recursive
 123  *      problems encountered when obtaining locking interfaces from libthread.
 124  *      The use of mutexes over reader/writer locks also enables the use of
 125  *      condition variables for controlling thread concurrency (allows access
 126  *      to objects only after their .init has completed).
 127  *
 128  * NOTE, the TI_VERSION indicated the ti_interface version number, where the
 129  * ti_interface was a large vector of functions passed to both libc (to override
 130  * the thread stub interfaces) and ld.so.1.  ld.so.1 used only a small subset of
 131  * these interfaces.
 132  *
 133  * CI_VERSION == 1
 134  *      Introduced with CI_VERSION & CI_ATEXIT
 135  *
 136  * CI_VERSION == 2 (Solaris 8 update 2).
 137  *      Added support for CI_LCMESSAGES
 138  *
 139  * CI_VERSION == 3 (Solaris 9).
 140  *      Added the following versions to the CI table:
 141  *
 142  *              CI_BIND_GUARD, CI_BIND_CLEAR, CI_THR_SELF
 143  *              CI_TLS_MODADD, CI_TLS_MOD_REMOVE, CI_TLS_STATMOD
 144  *
 145  *      This version introduced the DT_SUNW_RTLDINFO structure as a mechanism
 146  *      to handshake with ld.so.1.
 147  *
 148  * CI_VERSION == 4 (Solaris 10).
 149  *      Added the CI_THRINIT handshake as part of the libc/libthread unified
 150  *      process model.  libc now initializes the current thread pointer from
 151  *      this interface (and no longer relies on the INITFIRST flag - which
 152  *      others have started to camp out on).
 153  *
 154  * CI_VERSION == 5 (Solaris 11).
 155  *      Use of "protected" references within libc, so that symbols are
 156  *      pre-bound, and don't require ld.so.1 binding.  This implementation
 157  *      protects libc's critical regions from being vectored to auditors.
 158  *
 159  * CI_VERSION == 6 (Solaris 11).
 160  *      Added the CI_CRITICAL handshake, to allow "mem*" family to be reexposed
 161  *      as "global", and thus be redirected to auxiliary filters.
 162  *
 163  * Release summary:
 164  *
 165  *      Solaris 8       CI_ATEXIT via _ld_libc()
 166  *                      TI_* via _ld_concurrency()
 167  *
 168  *      Solaris 9       CI_ATEXIT and CI_LCMESSAGES via _ld_libc()
 169  *                      CI_* via RTLDINFO and _ld_libc()  - new libthread
 170  *                      TI_* via _ld_concurrency()  - old libthread
 171  *
 172  *      Solaris 10      CI_ATEXIT and CI_LCMESSAGES via _ld_libc()
 173  *                      CI_* via RTLDINFO and _ld_libc()  - new libthread
 174  */
 175 
 176 #include <sys/debug.h>
 177 #include <synch.h>
 178 #include <signal.h>
 179 #include <thread.h>
 180 #include <synch.h>
 181 #include <strings.h>
 182 #include <stdio.h>
 183 #include <debug.h>
 184 #include <libc_int.h>
 185 #include "_elf.h"
 186 #include "_rtld.h"
 187 
 188 /*
 189  * This interface provides the unified process model communication between
 190  * ld.so.1 and libc.  This interface can be called a number of times:
 191  *
 192  *   -  Initially, this interface is called to process RTLDINFO.  This data
 193  *      structure is typically provided by libc, and contains the address of
 194  *      libc interfaces that must be called to initialize threads information.
 195  *
 196  *   -  _ld_libc(), this interface can also be called by libc at process
 197  *      initialization, after libc has been loaded and relocated, but before
 198  *      control has been passed to any user code (.init's or main()).  This
 199  *      call provides additional libc interface information that ld.so.1 must
 200  *      call during process execution.
 201  *
 202  *   -  _ld_libc() can also be called by libc during process execution to
 203  *      re-establish interfaces such as the locale.
 204  */
 205 static void
 206 get_lcinterface(Rt_map *lmp, Lc_interface *funcs)
 207 {
 208         int             threaded = 0, entry = 0, tag;
 209         Lm_list         *lml;
 210         Lc_desc         *lcp;
 211 
 212         if ((lmp == NULL) || (funcs == NULL))
 213                 return;
 214 
 215         /*
 216          * Once the process is active, ensure we grab a lock.
 217          */
 218         if (rtld_flags & RT_FL_APPLIC)
 219                 entry = enter(0);
 220 
 221         lml = LIST(lmp);
 222         lcp = &lml->lm_lcs[0];
 223 
 224         DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD));
 225 
 226         for (tag = funcs->ci_tag; tag; tag = (++funcs)->ci_tag) {
 227                 char    *gptr;
 228                 char    *lptr = funcs->ci_un.ci_ptr;
 229 
 230                 DBG_CALL(Dbg_util_lcinterface(lmp, tag, lptr));
 231 
 232                 if (tag >= CI_MAX)
 233                         continue;
 234 
 235                 /*
 236                  * Maintain all interfaces on a per-link-map basis.  Note, for
 237                  * most interfaces, only the first interface is used for any
 238                  * link-map list.  This prevents accidents with developers who
 239                  * manage to load two different versions of libc.
 240                  */
 241                 if ((lcp[tag].lc_lmp) &&
 242                     (tag != CI_LCMESSAGES) && (tag != CI_VERSION)) {
 243                         DBG_CALL(Dbg_unused_lcinterface(lmp,
 244                             lcp[tag].lc_lmp, tag));
 245                         continue;
 246                 }
 247 
 248                 lcp[tag].lc_un.lc_ptr = lptr;
 249                 lcp[tag].lc_lmp = lmp;
 250 
 251                 gptr = glcs[tag].lc_un.lc_ptr;
 252 
 253                 /*
 254                  * Process any interfaces that must be maintained on a global
 255                  * basis.
 256                  */
 257                 switch (tag) {
 258                 case CI_ATEXIT:
 259                         break;
 260 
 261                 case CI_LCMESSAGES:
 262                         /*
 263                          * At startup, ld.so.1 can establish a locale from one
 264                          * of the locale family of environment variables (see
 265                          * ld_str_env() and readenv_user()).  During process
 266                          * execution the locale can also be changed by the user.
 267                          * This interface is called from libc should the locale
 268                          * be modified.  Presently, only one global locale is
 269                          * maintained for all link-map lists, and only objects
 270                          * on the primrary link-map may change this locale.
 271                          */
 272                         if ((lml->lm_flags & LML_FLG_BASELM) &&
 273                             ((gptr == NULL) || (strcmp(gptr, lptr) != 0))) {
 274                                 /*
 275                                  * If we've obtained a message locale (typically
 276                                  * supplied via libc's setlocale()), then
 277                                  * register the locale for use in dgettext() so
 278                                  * as to reestablish the locale for ld.so.1's
 279                                  * messages.
 280                                  */
 281                                 if (gptr) {
 282                                         free((void *)gptr);
 283                                         rtld_flags |= RT_FL_NEWLOCALE;
 284                                 }
 285                                 glcs[tag].lc_un.lc_ptr = strdup(lptr);
 286 
 287                                 /*
 288                                  * Clear any cached messages.
 289                                  */
 290                                 bzero(err_strs, sizeof (err_strs));
 291                                 nosym_str = NULL;
 292                         }
 293                         break;
 294 
 295                 case CI_BIND_GUARD:
 296                 case CI_BIND_CLEAR:
 297                 case CI_THR_SELF:
 298                 case CI_CRITICAL:
 299                         /*
 300                          * If the global vector is unset, or this is the primary
 301                          * link-map, set the global vector.
 302                          */
 303                         if ((gptr == NULL) || (lml->lm_flags & LML_FLG_BASELM))
 304                                 glcs[tag].lc_un.lc_ptr = lptr;
 305 
 306                         /* FALLTHROUGH */
 307 
 308                 case CI_TLS_MODADD:
 309                 case CI_TLS_MODREM:
 310                 case CI_TLS_STATMOD:
 311                 case CI_THRINIT:
 312                         threaded++;
 313                         break;
 314 
 315                 case CI_VERSION:
 316                         if ((rtld_flags2 & RT_FL2_RTLDSEEN) == 0) {
 317                                 Aliste  idx;
 318                                 Lm_list *lml2;
 319                                 int     version;
 320 
 321                                 rtld_flags2 |= RT_FL2_RTLDSEEN;
 322 
 323                                 version = funcs->ci_un.ci_val;
 324 #if defined(CI_V_FIVE)
 325                                 if (version >= CI_V_FIVE) {
 326                                         thr_flg_nolock = THR_FLG_NOLOCK;
 327                                         thr_flg_reenter = THR_FLG_REENTER;
 328                                 }
 329 #endif
 330                                 if (version < CI_V_FOUR)
 331                                         break;
 332 
 333                                 rtld_flags2 |= RT_FL2_UNIFPROC;
 334 
 335                                 /*
 336                                  * We might have seen an auditor which is not
 337                                  * dependent on libc.  Such an auditor's link
 338                                  * map list has LML_FLG_HOLDLOCK set.  This
 339                                  * lock needs to be dropped.  Refer to
 340                                  * audit_setup() in audit.c.
 341                                  */
 342                                 if ((rtld_flags2 & RT_FL2_HASAUDIT) == 0)
 343                                         break;
 344 
 345                                 /*
 346                                  * Yes, we did.  Take care of them.
 347                                  */
 348                                 for (APLIST_TRAVERSE(dynlm_list, idx, lml2)) {
 349                                         Rt_map *map = (Rt_map *)lml2->lm_head;
 350 
 351                                         if (FLAGS(map) & FLG_RT_AUDIT) {
 352                                                 lml2->lm_flags &=
 353                                                     ~LML_FLG_HOLDLOCK;
 354                                         }
 355                                 }
 356                         }
 357                         break;
 358 
 359                 default:
 360                         break;
 361                 }
 362         }
 363 
 364         if (threaded) {
 365                 /*
 366                  * If a version of libc gives us only a subset of the TLS
 367                  * interfaces, it's confused and we discard the whole lot.
 368                  */
 369                 if ((lcp[CI_TLS_MODADD].lc_un.lc_func &&
 370                     lcp[CI_TLS_MODREM].lc_un.lc_func &&
 371                     lcp[CI_TLS_STATMOD].lc_un.lc_func) == NULL) {
 372                         lcp[CI_TLS_MODADD].lc_un.lc_func = NULL;
 373                         lcp[CI_TLS_MODREM].lc_un.lc_func = NULL;
 374                         lcp[CI_TLS_STATMOD].lc_un.lc_func = NULL;
 375                 }
 376 
 377                 /*
 378                  * Indicate that we're now thread capable.
 379                  */
 380                 if ((lml->lm_flags & LML_FLG_RTLDLM) == 0)
 381                         rtld_flags |= RT_FL_THREADS;
 382         }
 383 
 384         if (entry)
 385                 leave(lml, 0);
 386 }
 387 
 388 /*
 389  * At this point we know we have a set of objects that have been fully analyzed
 390  * and relocated.  Prior to the next major step of running .init sections (ie.
 391  * running user code), retrieve any RTLDINFO interfaces.
 392  */
 393 int
 394 rt_get_extern(Lm_list *lml, Rt_map *lmp)
 395 {
 396         if (lml->lm_rti) {
 397                 Aliste          idx;
 398                 Rti_desc        *rti;
 399 
 400                 for (ALIST_TRAVERSE(lml->lm_rti, idx, rti))
 401                         get_lcinterface(rti->rti_lmp, rti->rti_info);
 402 
 403                 free(lml->lm_rti);
 404                 lml->lm_rti = 0;
 405         }
 406 
 407         /*
 408          * Perform some sanity checks.  If we have TLS requirements we better
 409          * have the associated external interfaces.
 410          */
 411         if (lml->lm_tls &&
 412             (lml->lm_lcs[CI_TLS_STATMOD].lc_un.lc_func == NULL)) {
 413                 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_TLS_NOSUPPORT),
 414                     NAME(lmp));
 415                 return (0);
 416         }
 417         return (1);
 418 }
 419 
 420 /*
 421  * Provide an interface for libc to communicate additional interface
 422  * information.
 423  */
 424 void
 425 _ld_libc(void *ptr)
 426 {
 427         get_lcinterface(_caller(caller(), CL_EXECDEF), (Lc_interface *)ptr);
 428 }
 429 
 430 static int      bindmask = 0;
 431 
 432 int
 433 rt_bind_guard(int flags)
 434 {
 435         int     (*fptr)(int);
 436         int     bindflag;
 437 
 438         if ((fptr = glcs[CI_BIND_GUARD].lc_un.lc_func) != NULL) {
 439                 return ((*fptr)(flags));
 440         } else {
 441                 bindflag = (flags & THR_FLG_RTLD);
 442                 if ((bindflag & bindmask) == 0) {
 443                         bindmask |= bindflag;
 444                         return (1);
 445                 }
 446                 return (0);
 447         }
 448 }
 449 
 450 int
 451 rt_bind_clear(int flags)
 452 {
 453         int     (*fptr)(int);
 454         int     bindflag;
 455 
 456         if ((fptr = glcs[CI_BIND_CLEAR].lc_un.lc_func) != NULL) {
 457                 return ((*fptr)(flags));
 458         } else {
 459                 bindflag = (flags & THR_FLG_RTLD);
 460                 if (bindflag == 0)
 461                         return (bindmask);
 462                 else {
 463                         bindmask &= ~bindflag;
 464                         return (0);
 465                 }
 466         }
 467 }
 468 
 469 /*
 470  * Make sure threads have been initialized.  This interface is called once for
 471  * each link-map list.
 472  */
 473 void
 474 rt_thr_init(Lm_list *lml)
 475 {
 476         void    (*fptr)(void);
 477 
 478         if ((fptr =
 479             (void (*)())lml->lm_lcs[CI_THRINIT].lc_un.lc_func) != NULL) {
 480                 lml->lm_lcs[CI_THRINIT].lc_un.lc_func = NULL;
 481 
 482                 leave(lml, thr_flg_reenter);
 483                 (*fptr)();
 484                 (void) enter(thr_flg_reenter);
 485 
 486                 /*
 487                  * If this is an alternative link-map list, and this is the
 488                  * first call to initialize threads, don't let the destination
 489                  * libc be deleted.  It is possible that an auditors complete
 490                  * initialization fails, but there is presently no main link-map
 491                  * list.  As this libc has established the thread pointer, don't
 492                  * delete this libc, otherwise the initialization of libc on the
 493                  * main link-map can be compromised during its threads
 494                  * initialization.
 495                  */
 496                 if (((lml->lm_flags & LML_FLG_BASELM) == 0) &&
 497                     ((rtld_flags2 & RT_FL2_PLMSETUP) == 0))
 498                         MODE(lml->lm_lcs[CI_THRINIT].lc_lmp) |= RTLD_NODELETE;
 499         }
 500 }
 501 
 502 thread_t
 503 rt_thr_self()
 504 {
 505         thread_t        (*fptr)(void);
 506 
 507         if ((fptr = (thread_t (*)())glcs[CI_THR_SELF].lc_un.lc_func) != NULL)
 508                 return ((*fptr)());
 509 
 510         return (1);
 511 }
 512 
 513 int
 514 rt_mutex_lock(Rt_lock *mp)
 515 {
 516         return (_lwp_mutex_lock((lwp_mutex_t *)mp));
 517 }
 518 
 519 int
 520 rt_mutex_unlock(Rt_lock *mp)
 521 {
 522         return (_lwp_mutex_unlock((lwp_mutex_t *)mp));
 523 }
 524 
 525 /*
 526  * Test whether we're in a libc critical region.  Certain function references,
 527  * like the "mem*" family, might require binding.  Although these functions can
 528  * safely bind to auxiliary filtees, they should not be captured by auditors.
 529  */
 530 int
 531 rt_critical()
 532 {
 533         int     (*fptr)(void);
 534 
 535         if ((fptr = glcs[CI_CRITICAL].lc_un.lc_func) != NULL)
 536                 return ((*fptr)());
 537 
 538         return (0);
 539 }
 540 
 541 /*
 542  * Mutex interfaces to resolve references from any objects extracted from
 543  * libc_pic.a.  Note, as ld.so.1 is essentially single threaded these can be
 544  * noops.
 545  */
 546 #pragma weak lmutex_lock = mutex_lock
 547 /* ARGSUSED */
 548 int
 549 mutex_lock(mutex_t *mp)
 550 {
 551         return (0);
 552 }
 553 
 554 #pragma weak lmutex_unlock = mutex_unlock
 555 /* ARGSUSED */
 556 int
 557 mutex_unlock(mutex_t *mp)
 558 {
 559         return (0);
 560 }
 561 
 562 /* ARGSUSED */
 563 int
 564 mutex_init(mutex_t *mp, int type, void *arg)
 565 {
 566         return (0);
 567 }
 568 
 569 /* ARGSUSED */
 570 int
 571 mutex_destroy(mutex_t *mp)
 572 {
 573         return (0);
 574 }
 575 
 576 /*
 577  * This is needed to satisfy sysconf() (case _SC_THREAD_STACK_MIN)
 578  */
 579 size_t
 580 thr_min_stack()
 581 {
 582         return (sizeof (uintptr_t) * 1024);
 583 }
 584 
 585 /*
 586  * Local str[n]casecmp() interfaces for the dynamic linker,
 587  * to avoid problems when linking with libc_pic.a
 588  */
 589 int
 590 strcasecmp(const char *s1, const char *s2)
 591 {
 592         extern int ascii_strcasecmp(const char *, const char *);
 593 
 594         return (ascii_strcasecmp(s1, s2));
 595 }
 596 
 597 int
 598 strncasecmp(const char *s1, const char *s2, size_t n)
 599 {
 600         extern int ascii_strncasecmp(const char *, const char *, size_t);
 601 
 602         return (ascii_strncasecmp(s1, s2, n));
 603 }
 604 
 605 /*
 606  * The following functions are cancellation points in libc.
 607  * They are called from other functions in libc that we extract
 608  * and use directly.  We don't do cancellation while we are in
 609  * the dynamic linker, so we redefine these to call the primitive,
 610  * non-cancellation interfaces.
 611  */
 612 int
 613 close(int fildes)
 614 {
 615         extern int __close(int);
 616 
 617         return (__close(fildes));
 618 }
 619 
 620 int
 621 fcntl(int fildes, int cmd, ...)
 622 {
 623         extern int __fcntl(int, int, ...);
 624         intptr_t arg;
 625         va_list ap;
 626 
 627         va_start(ap, cmd);
 628         arg = va_arg(ap, intptr_t);
 629         va_end(ap);
 630         return (__fcntl(fildes, cmd, arg));
 631 }
 632 
 633 int
 634 open(const char *path, int oflag, ...)
 635 {
 636         extern int __open(const char *, int, mode_t);
 637         mode_t mode;
 638         va_list ap;
 639 
 640         va_start(ap, oflag);
 641         mode = va_arg(ap, mode_t);
 642         va_end(ap);
 643         return (__open(path, oflag, mode));
 644 }
 645 
 646 int
 647 openat(int fd, const char *path, int oflag, ...)
 648 {
 649         extern int __openat(int, const char *, int, mode_t);
 650         mode_t mode;
 651         va_list ap;
 652 
 653         va_start(ap, oflag);
 654         mode = va_arg(ap, mode_t);
 655         va_end(ap);
 656         return (__openat(fd, path, oflag, mode));
 657 }
 658 
 659 ssize_t
 660 read(int fd, void *buf, size_t size)
 661 {
 662         extern ssize_t __read(int, void *, size_t);
 663         return (__read(fd, buf, size));
 664 }
 665 
 666 ssize_t
 667 write(int fd, const void *buf, size_t size)
 668 {
 669         extern ssize_t __write(int, const void *, size_t);
 670         return (__write(fd, buf, size));
 671 }
 672 
 673 /*
 674  * ASCII versions of ctype character classification functions.  This avoids
 675  * pulling in the entire locale framework that is in libc.
 676  */
 677 
 678 int
 679 isdigit(int c)
 680 {
 681         return ((c >= '0' && c <= '9') ? 1 : 0);
 682 }
 683 
 684 int
 685 isupper(int c)
 686 {
 687         return ((c >= 'A' && c <= 'Z') ? 1 : 0);
 688 }
 689 
 690 int
 691 islower(int c)
 692 {
 693         return ((c >= 'a' && c <= 'z') ? 1 : 0);
 694 }
 695 
 696 int
 697 isspace(int c)
 698 {
 699         return (((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n') ||
 700             (c == '\v') || (c == '\f')) ? 1 : 0);
 701 }
 702 
 703 int
 704 isxdigit(int c)
 705 {
 706         return ((isdigit(c) || (c >= 'A' && c <= 'F') ||
 707             (c >= 'a' && c <= 'f')) ? 1 : 0);
 708 }
 709 
 710 int
 711 isalpha(int c)
 712 {
 713         return ((isupper(c) || islower(c)) ? 1 : 0);
 714 }
 715 
 716 int
 717 isalnum(int c)
 718 {
 719         return ((isalpha(c) || isdigit(c)) ? 1 : 0);
 720 }