コード例 #1
0
ファイル: nisplus-ethers.c プロジェクト: alucas/glibc
enum nss_status
_nss_nisplus_endetherent (void)
{
  __libc_lock_lock (lock);

  if (result != NULL)
    {
      nis_freeresult (result);
      result = NULL;
    }

  __libc_lock_unlock (lock);

  return NSS_STATUS_SUCCESS;
}
コード例 #2
0
ファイル: getnetgrent_r.c プロジェクト: RobbenBasten/glibc
int
setnetgrent (const char *group)
{
  int result;

  __libc_lock_lock (lock);

  result = nscd_setnetgrent (group);
  if (result < 0)
    result = __internal_setnetgrent (group, &dataset);

  __libc_lock_unlock (lock);

  return result;
}
コード例 #3
0
ファイル: getnetgrent_r.c プロジェクト: RobbenBasten/glibc
/* The real entry point.  */
int
__getnetgrent_r (char **hostp, char **userp, char **domainp,
		 char *buffer, size_t buflen)
{
  enum nss_status status;

  __libc_lock_lock (lock);

  status = __internal_getnetgrent_r (hostp, userp, domainp, &dataset,
				     buffer, buflen, &errno);

  __libc_lock_unlock (lock);

  return status;
}
コード例 #4
0
int
__nss_configure_lookup (const char *dbname, const char *service_line)
{
  service_user *new_db;
  size_t cnt;

  for (cnt = 0; cnt < sizeof databases; ++cnt)
    {
      int cmp = strcmp (dbname, databases[cnt].name);
      if (cmp == 0)
	break;
      if (cmp < 0)
	{
	  __set_errno (EINVAL);
	  return -1;
	}
    }

  if (cnt == sizeof databases)
    {
      __set_errno (EINVAL);
      return -1;
    }

  /* Test whether it is really used.  */
  if (databases[cnt].dbp == NULL)
    /* Nothing to do, but we could do.  */
    return 0;

  /* Try to generate new data.  */
  new_db = nss_parse_service_list (service_line);
  if (new_db == NULL)
    {
      /* Illegal service specification.  */
      __set_errno (EINVAL);
      return -1;
    }

  /* Prevent multiple threads to change the service table.  */
  __libc_lock_lock (lock);

  /* Install new rules.  */
  *databases[cnt].dbp = new_db;

  __libc_lock_unlock (lock);

  return 0;
}
コード例 #5
0
ファイル: nis-pwd.c プロジェクト: JamesLinus/glibc-mips
enum nss_status
_nss_nis_setpwent (int stayopen)
{
  enum nss_status result = NSS_STATUS_SUCCESS;

  __libc_lock_lock (lock);

  internal_nis_endpwent ();

  if (_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ)
    result = internal_nis_setpwent ();

  __libc_lock_unlock (lock);

  return result;
}
コード例 #6
0
ファイル: sbrk.c プロジェクト: 7perl/akaros
/* Extend the process's data space by INCREMENT.
   If INCREMENT is negative, shrink data space by - INCREMENT.
   Return start of new space allocated, or -1 for errors.  */
void *
__sbrk (intptr_t increment)
{
  __libc_lock_lock(brk_lock);

  uintptr_t oldbrk = __internal_getbrk();
  if ((increment > 0
       ? (oldbrk + (uintptr_t) increment < oldbrk)
       : (oldbrk < (uintptr_t) -increment))
      || __internal_setbrk (oldbrk + increment) < 0)
    oldbrk = -1;

  __libc_lock_unlock(brk_lock);

  return (void*)oldbrk;
}
コード例 #7
0
ファイル: random.c プロジェクト: bminor/glibc
/* Restore the state from the given state array.
   Note: It is important that we also remember the locations of the pointers
   in the current state information, and restore the locations of the pointers
   from the old state information.  This is done by multiplexing the pointer
   location into the zeroth word of the state information. Note that due
   to the order in which things are done, it is OK to call setstate with the
   same state as the current state
   Returns a pointer to the old state information.  */
char *
__setstate (char *arg_state)
{
  int32_t *ostate;

  __libc_lock_lock (lock);

  ostate = &unsafe_state.state[-1];

  if (__setstate_r (arg_state, &unsafe_state) < 0)
    ostate = NULL;

  __libc_lock_unlock (lock);

  return (char *) ostate;
}
コード例 #8
0
ファイル: random.c プロジェクト: bminor/glibc
/* Initialize the state information in the given array of N bytes for
   future random number generation.  Based on the number of bytes we
   are given, and the break values for the different R.N.G.'s, we choose
   the best (largest) one we can and set things up for it.  srandom is
   then called to initialize the state information.  Note that on return
   from srandom, we set state[-1] to be the type multiplexed with the current
   value of the rear pointer; this is so successive calls to initstate won't
   lose this information and will be able to restart with setstate.
   Note: The first thing we do is save the current state, if any, just like
   setstate so that it doesn't matter when initstate is called.
   Returns a pointer to the old state.  */
char *
__initstate (unsigned int seed, char *arg_state, size_t n)
{
  int32_t *ostate;
  int ret;

  __libc_lock_lock (lock);

  ostate = &unsafe_state.state[-1];

  ret = __initstate_r (seed, arg_state, n, &unsafe_state);

  __libc_lock_unlock (lock);

  return ret == -1 ? NULL : (char *) ostate;
}
コード例 #9
0
ファイル: getXXent_r.c プロジェクト: JamesLinus/glibc-mips
void
ENDFUNC_NAME (void)
{
  int save;

  /* If the service has not been used before do not do anything.  */
  if (startp != NULL)
    {
      __libc_lock_lock (lock);
      __nss_endent (ENDFUNC_NAME_STRING, DB_LOOKUP_FCT, &nip, &startp,
		    &last_nip, NEED__RES);
      save = errno;
      __libc_lock_unlock (lock);
      __set_errno (save);
    }
}
コード例 #10
0
ファイル: opensock.c プロジェクト: JamesLinus/glibc-mips
/* Return a socket of any type.  The socket can be used in subsequent
   ioctl calls to talk to the kernel.  */
int internal_function
__opensock (void)
{
  /* Cache the last AF that worked, to avoid many redundant calls to
     socket().  */
  static int sock_af = -1;
  int fd = -1;
  __libc_lock_define_initialized (static, lock);

  if (sock_af != -1)
    {
      fd = __socket (sock_af, SOCK_DGRAM, 0);
      if (fd != -1)
        return fd;
    }

  __libc_lock_lock (lock);

  if (sock_af != -1)
    fd = __socket (sock_af, SOCK_DGRAM, 0);

  if (fd == -1)
    {
#ifdef AF_INET
      fd = __socket (sock_af = AF_INET, SOCK_DGRAM, 0);
#endif
#ifdef AF_INET6
      if (fd < 0)
	fd = __socket (sock_af = AF_INET6, SOCK_DGRAM, 0);
#endif
#ifdef AF_IPX
      if (fd < 0)
	fd = __socket (sock_af = AF_IPX, SOCK_DGRAM, 0);
#endif
#ifdef AF_AX25
      if (fd < 0)
	fd = __socket (sock_af = AF_AX25, SOCK_DGRAM, 0);
#endif
#ifdef AF_APPLETALK
      if (fd < 0)
	fd = __socket (sock_af = AF_APPLETALK, SOCK_DGRAM, 0);
#endif
    }

  __libc_lock_unlock (lock);
  return fd;
}
コード例 #11
0
ファイル: sgetspent.c プロジェクト: Drakey83/steamlink-sdk
/* Read one shadow entry from the given stream.  */
struct spwd *
sgetspent (const char *string)
{
  static char *buffer;
  static size_t buffer_size;
  static struct spwd resbuf;
  struct spwd *result;
  int save;

  /* Get lock.  */
  __libc_lock_lock (lock);

  /* Allocate buffer if not yet available.  */
  if (buffer == NULL)
    {
      buffer_size = BUFLEN_SPWD;
      buffer = malloc (buffer_size);
    }

  while (buffer != NULL
	 && (__sgetspent_r (string, &resbuf, buffer, buffer_size, &result)
	     == ERANGE))
    {
      char *new_buf;
      buffer_size += BUFLEN_SPWD;
      new_buf = realloc (buffer, buffer_size);
      if (new_buf == NULL)
	{
	  /* We are out of memory.  Free the current buffer so that the
	     process gets a chance for a normal termination.  */
	  save = errno;
	  free (buffer);
	  __set_errno (save);
	}
      buffer = new_buf;
    }

  if (buffer == NULL)
    result = NULL;

  /* Release lock.  Preserve error value.  */
  save = errno;
  __libc_lock_unlock (lock);
  __set_errno (save);

  return result;
}
コード例 #12
0
ファイル: nis-network.c プロジェクト: AubrCool/glibc
enum nss_status
_nss_nis_setnetent (int stayopen)
{
  __libc_lock_lock (lock);

  new_start = 1;
  if (oldkey != NULL)
    {
      free (oldkey);
      oldkey = NULL;
      oldkeylen = 0;
    }

  __libc_lock_unlock (lock);

  return NSS_STATUS_SUCCESS;
}
コード例 #13
0
ファイル: nisplus-grp.c プロジェクト: riscv/riscv-glibc
enum nss_status
_nss_nisplus_setgrent (int stayopen)
{
  enum nss_status status;

  __libc_lock_lock (lock);

  internal_endgrent ();

  // XXX We need to be able to set errno.  Pass in new parameter.
  int err;
  status = internal_setgrent (&err);

  __libc_lock_unlock (lock);

  return status;
}
コード例 #14
0
enum nss_status
_nss_nis_endetherent (void)
{
  __libc_lock_lock (lock);

  new_start = 1;
  if (oldkey != NULL)
    {
      free (oldkey);
      oldkey = NULL;
      oldkeylen = 0;
    }

  __libc_lock_unlock (lock);

  return NSS_STATUS_SUCCESS;
}
コード例 #15
0
/* Close the directory stream DIRP.
   Return 0 if successful, -1 if not.  */
int
__closedir (DIR *dirp)
{
  if (dirp == NULL) {
     __set_errno (EINVAL);
     return -1;
  }
  if (dirp->fd == INVALID_DIRFD) {
  	__set_errno (EBADF);
	return -1;
  }	
  __libc_lock_lock (dirp->lock);
  rewinddir (dirp);
  free(dirp->data);
  free (dirp);
  __libc_lock_unlock (dirp->lock);
  return 0;
}
コード例 #16
0
/* Open the database.  */
enum nss_status
CONCAT(_nss_db_set,ENTNAME) (int stayopen)
{
  enum nss_status status;

  __libc_lock_lock (lock);

  status = internal_setent (DBFILE, &db);

  /* Remember STAYOPEN flag.  */
  if (db != NULL)
    keep_db |= stayopen;
  /* Reset the sequential index.  */
  entidx = 0;

  __libc_lock_unlock (lock);

  return status;
}
コード例 #17
0
ファイル: arena.c プロジェクト: kraj/glibc
arena_thread_freeres (void)
{
  mstate a = thread_arena;
  thread_arena = NULL;

  if (a != NULL)
    {
      __libc_lock_lock (free_list_lock);
      /* If this was the last attached thread for this arena, put the
	 arena on the free list.  */
      assert (a->attached_threads > 0);
      if (--a->attached_threads == 0)
	{
	  a->next_free = free_list;
	  free_list = a;
	}
      __libc_lock_unlock (free_list_lock);
    }
}
コード例 #18
0
/* Initialize the NSS interface/functions. The calling function must
   hold the lock.  */
static void
init_nss_interface (void)
{
  __libc_lock_lock (lock);

  /* Retest.  */
  if (ni == NULL
      && __nss_database_lookup ("group_compat", NULL, "nis", &ni) >= 0)
    {
      nss_initgroups_dyn = __nss_lookup_function (ni, "initgroups_dyn");
      nss_setgrent = __nss_lookup_function (ni, "setgrent");
      nss_getgrnam_r = __nss_lookup_function (ni, "getgrnam_r");
      nss_getgrgid_r = __nss_lookup_function (ni, "getgrgid_r");
      nss_getgrent_r = __nss_lookup_function (ni, "getgrent_r");
      nss_endgrent = __nss_lookup_function (ni, "endgrent");
    }

  __libc_lock_unlock (lock);
}
コード例 #19
0
enum nss_status
_nss_nisplus_setspent (int stayopen)
{
  enum nss_status status = NSS_STATUS_SUCCESS;
  int err;

  __libc_lock_lock (lock);

  if (result)
    nis_freeresult (result);
  result = NULL;

  if (tablename_val == NULL)
    status = _nss_create_tablename (&err);

  __libc_lock_unlock (lock);

  return NSS_STATUS_SUCCESS;
}
コード例 #20
0
int
__utmpname (const char *file)
{
  int result = -1;

  __libc_lock_lock (__libc_utmp_lock);

  /* Close the old file.  */
  (*__libc_utmp_jump_table->endutent) ();
  __libc_utmp_jump_table = &__libc_utmp_unknown_functions;

  if (strcmp (file, __libc_utmp_file_name) != 0)
    {
      if (strcmp (file, default_file_name) == 0)
	{
	  if (__libc_utmp_file_name != default_file_name)
	    free ((char *) __libc_utmp_file_name);

	  __libc_utmp_file_name = default_file_name;
	}
      else
	{
	  char *file_name = __strdup (file);
	  if (file_name == NULL)
	    /* Out of memory.  */
	    goto done;

	  if (__libc_utmp_file_name != default_file_name)
	    free ((char *) __libc_utmp_file_name);

	  __libc_utmp_file_name = file_name;
	}
    }

  result = 0;

done:
  __libc_lock_unlock (__libc_utmp_lock);
  return result;
}
コード例 #21
0
unsigned long
_create_xid (void)
{
  long int res;

  __libc_lock_lock (createxid_lock);

  if (!is_initialized)
    {
      struct timeval now;

      __gettimeofday (&now, (struct timezone *) 0);
      __srand48_r (now.tv_sec ^ now.tv_usec, &__rpc_lrand48_data);
      is_initialized = 1;
    }

  lrand48_r (&__rpc_lrand48_data, &res);

  __libc_lock_unlock (createxid_lock);

  return res;
}
コード例 #22
0
ファイル: files-XXX.c プロジェクト: SvenDowideit/clearlinux
/* Thread-safe, exported version of that.  */
enum nss_status
CONCAT(CONCAT(CONCAT(_nss_, ALTFILES_MODULE_NAME), _set), ENTNAME) (int stayopen)
{
  enum nss_status status;

  __libc_lock_lock (lock);

  status = internal_setent (stayopen);

  if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
    {
      fclose (stream);
      stream = NULL;
      status = NSS_STATUS_UNAVAIL;
    }

  last_use = getent;

  __libc_lock_unlock (lock);

  return status;
}
コード例 #23
0
ファイル: nisplus-ethers.c プロジェクト: alucas/glibc
enum nss_status
_nss_nisplus_setetherent (int stayopen)
{
  enum nss_status status;
  int err;

  status = NSS_STATUS_SUCCESS;

  __libc_lock_lock (lock);

  if (result != NULL)
    {
      nis_freeresult (result);
      result = NULL;
    }

  if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS)
    status = NSS_STATUS_UNAVAIL;

  __libc_lock_unlock (lock);

  return status;
}
コード例 #24
0
void
__freelocale (__locale_t dataset)
{
  int cnt;

  /* This static object is returned for newlocale (LC_ALL_MASK, "C").  */
  if (dataset == _nl_C_locobj_ptr)
    return;

  /* We modify global data (the usage counts).  */
  __libc_lock_lock (__libc_setlocale_lock);

  for (cnt = 0; cnt < __LC_LAST; ++cnt)
    if (cnt != LC_ALL && dataset->__locales[cnt]->usage_count != UNDELETABLE)
      /* We can remove the data.  */
      _nl_remove_locale (cnt, dataset->__locales[cnt]);

  /* It's done.  */
  __libc_lock_unlock (__libc_setlocale_lock);

  /* Free the locale_t handle itself.  */
  free (dataset);
}
コード例 #25
0
ファイル: lc-time.c プロジェクト: BackupTheBerlios/wl530g-svn
const char *
_nl_get_alt_digit (unsigned int number)
{
  const char *result;

  __libc_lock_lock (__libc_setlocale_lock);

  if (alt_digits_initialized == 0)
    {
      alt_digits_initialized = 1;

      if (alt_digits == NULL)
	alt_digits = malloc (100 * sizeof (const char *));

      if (alt_digits != NULL)
	{
	  const char *ptr = _NL_CURRENT (LC_TIME, ALT_DIGITS);
	  size_t cnt;

	  if (alt_digits != NULL)
	    for (cnt = 0; cnt < 100; ++cnt)
	      {
		alt_digits[cnt] = ptr;

		/* Skip digit format. */
		ptr = strchr (ptr, '\0') + 1;
	      }
	}
    }

  result = alt_digits != NULL && number < 100 ? alt_digits[number] : NULL;

  __libc_lock_unlock (__libc_setlocale_lock);

  return result;
}
コード例 #26
0
ファイル: lckpwdf.c プロジェクト: Lind-Project/Lind-GlibC
int
__ulckpwdf (void)
{
  int result;

  if (lock_fd == -1)
    /* There is no lock set.  */
    result = -1;
  else
    {
      /* Prevent problems caused by multiple threads.  */
      __libc_lock_lock (lock);

      result = __close (lock_fd);

      /* Mark descriptor as unused.  */
      lock_fd = -1;

      /* Clear mutex.  */
      __libc_lock_unlock (lock);
    }

  return result;
}
コード例 #27
0
ファイル: fork.c プロジェクト: kstraube/rampgold_fixed
/* Clone the calling process, creating an exact copy.
   Return -1 for errors, 0 to the new process,
   and the process ID of the new process to the old process.  */
int
__fork ()
{
  int ret = -1;
  __libc_lock_lock(__fork_lock);

  if(child_list_size == child_list_capacity)
  {
    int newcap = child_list_capacity ? 2*child_list_capacity : 1;
    int* tmp = realloc(child_list,newcap*sizeof(int));
    if(!tmp)
      goto out;
    child_list_capacity = newcap;
    child_list = tmp;
  }

  ret = ros_syscall(SYS_fork,0,0,0,0,0);
  if(ret > 0)
    child_list[child_list_size++] = ret;

out:
  __libc_lock_unlock(__fork_lock);
  return ret;
}
コード例 #28
0
ファイル: syslog.c プロジェクト: KubaKaszycki/kklibc
void
__vsyslog_chk(int pri, int flag, const char *fmt, va_list ap)
{
    struct tm now_tm;
    time_t now;
    int fd;
    FILE *f;
    char *buf = 0;
    size_t bufsize = 0;
    size_t msgoff;
#ifndef NO_SIGPIPE
    struct sigaction action, oldaction;
    int sigpipe;
#endif
    int saved_errno = errno;
    char failbuf[3 * sizeof (pid_t) + sizeof "out of memory []"];

#define	INTERNALLOG	LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
    /* Check for invalid bits. */
    if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) {
        syslog(INTERNALLOG,
               "syslog: unknown facility/priority: %x", pri);
        pri &= LOG_PRIMASK|LOG_FACMASK;
    }

    /* Check priority against setlogmask values. */
    if ((LOG_MASK (LOG_PRI (pri)) & LogMask) == 0)
        return;

    /* Set default facility if none specified. */
    if ((pri & LOG_FACMASK) == 0)
        pri |= LogFacility;

    /* Build the message in a memory-buffer stream.  */
    f = __open_memstream (&buf, &bufsize);
    if (f == NULL)
    {
        /* We cannot get a stream.  There is not much we can do but
           emitting an error messages.  */
        char numbuf[3 * sizeof (pid_t)];
        char *nump;
        char *endp = __stpcpy (failbuf, "out of memory [");
        pid_t pid = __getpid ();

        nump = numbuf + sizeof (numbuf);
        /* The PID can never be zero.  */
        do
            *--nump = '0' + pid % 10;
        while ((pid /= 10) != 0);

        endp = __mempcpy (endp, nump, (numbuf + sizeof (numbuf)) - nump);
        *endp++ = ']';
        *endp = '\0';
        buf = failbuf;
        bufsize = endp - failbuf;
        msgoff = 0;
    }
    else
    {
        __fsetlocking (f, FSETLOCKING_BYCALLER);
        fprintf (f, "<%d>", pri);
        (void) time (&now);
        f->_IO_write_ptr += __strftime_l (f->_IO_write_ptr,
                                          f->_IO_write_end
                                          - f->_IO_write_ptr,
                                          "%h %e %T ",
                                          __localtime_r (&now, &now_tm),
                                          _nl_C_locobj_ptr);
        msgoff = ftell (f);
        if (LogTag == NULL)
            LogTag = __progname;
        if (LogTag != NULL)
            __fputs_unlocked (LogTag, f);
        if (LogStat & LOG_PID)
            fprintf (f, "[%d]", (int) __getpid ());
        if (LogTag != NULL)
        {
            putc_unlocked (':', f);
            putc_unlocked (' ', f);
        }

        /* Restore errno for %m format.  */
        __set_errno (saved_errno);

        /* We have the header.  Print the user's format into the
               buffer.  */
        if (flag == -1)
            vfprintf (f, fmt, ap);
        else
            __vfprintf_chk (f, flag, fmt, ap);

        /* Close the memory stream; this will finalize the data
           into a malloc'd buffer in BUF.  */
        fclose (f);
    }

    /* Output to stderr if requested. */
    if (LogStat & LOG_PERROR) {
        struct iovec iov[2];
        struct iovec *v = iov;

        v->iov_base = buf + msgoff;
        v->iov_len = bufsize - msgoff;
        /* Append a newline if necessary.  */
        if (buf[bufsize - 1] != '\n')
        {
            ++v;
            v->iov_base = (char *) "\n";
            v->iov_len = 1;
        }

        __libc_cleanup_push (free, buf == failbuf ? NULL : buf);

        /* writev is a cancellation point.  */
        (void)__writev(STDERR_FILENO, iov, v - iov + 1);

        __libc_cleanup_pop (0);
    }

    /* Prepare for multiple users.  We have to take care: open and
       write are cancellation points.  */
    struct cleanup_arg clarg;
    clarg.buf = buf;
    clarg.oldaction = NULL;
    __libc_cleanup_push (cancel_handler, &clarg);
    __libc_lock_lock (syslog_lock);

#ifndef NO_SIGPIPE
    /* Prepare for a broken connection.  */
    memset (&action, 0, sizeof (action));
    action.sa_handler = sigpipe_handler;
    sigemptyset (&action.sa_mask);
    sigpipe = __sigaction (SIGPIPE, &action, &oldaction);
    if (sigpipe == 0)
        clarg.oldaction = &oldaction;
#endif

    /* Get connected, output the message to the local logger. */
    if (!connected)
        openlog_internal(LogTag, LogStat | LOG_NDELAY, 0);

    /* If we have a SOCK_STREAM connection, also send ASCII NUL as
       a record terminator.  */
    if (LogType == SOCK_STREAM)
        ++bufsize;

    if (!connected || __send(LogFile, buf, bufsize, send_flags) < 0)
    {
        if (connected)
        {
            /* Try to reopen the syslog connection.  Maybe it went
               down.  */
            closelog_internal ();
            openlog_internal(LogTag, LogStat | LOG_NDELAY, 0);
        }

        if (!connected || __send(LogFile, buf, bufsize, send_flags) < 0)
        {
            closelog_internal ();	/* attempt re-open next time */
            /*
             * Output the message to the console; don't worry
             * about blocking, if console blocks everything will.
             * Make sure the error reported is the one from the
             * syslogd failure.
             */
            if (LogStat & LOG_CONS &&
                    (fd = __open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY, 0)) >= 0)
            {
                __dprintf (fd, "%s\r\n", buf + msgoff);
                (void)__close(fd);
            }
        }
    }

#ifndef NO_SIGPIPE
    if (sigpipe == 0)
        __sigaction (SIGPIPE, &oldaction, (struct sigaction *) NULL);
#endif

    /* End of critical section.  */
    __libc_cleanup_pop (0);
    __libc_lock_unlock (syslog_lock);

    if (buf != failbuf)
        free (buf);
}
コード例 #29
0
ファイル: lc-time.c プロジェクト: ljegege/linux-source
struct era_entry *
_nl_get_era_entry (const struct tm *tp)
{
  struct era_entry *result;
  size_t cnt;

  __libc_lock_lock (__libc_setlocale_lock);

  if (era_initialized == 0)
    {
      size_t new_num_eras = _NL_CURRENT_WORD (LC_TIME,
					      _NL_TIME_ERA_NUM_ENTRIES);

      if (eras != NULL && new_num_eras == 0)
	{
	  free (eras);
	  eras = NULL;
	}
      else if (new_num_eras != 0)
	{
	  if (num_eras != new_num_eras)
	    eras = realloc (eras, new_num_eras * sizeof (struct era_entry *));

	  if (eras == NULL)
	    num_eras = 0;
	  else
	    {
#if __BYTE_ORDER == __LITTLE_ENDIAN
	      const char *ptr = _NL_CURRENT (LC_TIME, _NL_TIME_ERA_ENTRIES_EL);
#else
	      const char *ptr = _NL_CURRENT (LC_TIME, _NL_TIME_ERA_ENTRIES_EB);
#endif
	      num_eras = new_num_eras;

	      for (cnt = 0; cnt < num_eras; ++cnt)
		{
		  eras[cnt] = (struct era_entry *) ptr;

		  /* Skip numeric values.  */
		  ptr += sizeof (struct era_entry);
		  /* Skip era name. */
		  ptr = strchr (ptr, '\0') + 1;
		  /* Skip era format. */
		  ptr = strchr (ptr, '\0') + 1;

		  ptr += 3 - (((ptr - (const char *) eras[cnt]) + 3) & 3);
		}
	    }
	}

      era_initialized = 1;
    }

  /* Now compare date with the available eras.  */
  for (cnt = 0; cnt < num_eras; ++cnt)
    if ((eras[cnt]->start_date[0] < tp->tm_year
	 || (eras[cnt]->start_date[0] == tp->tm_year
	     && (eras[cnt]->start_date[1] < tp->tm_mon
		 || (eras[cnt]->start_date[1] == tp->tm_mon
		     && eras[cnt]->start_date[2] <= tp->tm_mday))))
	&& (eras[cnt]->stop_date[0] > tp->tm_year
	    || (eras[cnt]->stop_date[0] == tp->tm_year
		&& (eras[cnt]->stop_date[1] > tp->tm_mon
		    || (eras[cnt]->stop_date[1] == tp->tm_mon
			&& eras[cnt]->stop_date[2] >= tp->tm_mday)))))
      break;

  result = cnt < num_eras ? eras[cnt] : NULL;

  __libc_lock_unlock (__libc_setlocale_lock);

  return result;
}
コード例 #30
0
ファイル: getXXbyYY.c プロジェクト: JamesLinus/glibc-mips
LOOKUP_TYPE *
FUNCTION_NAME (ADD_PARAMS)
{
  static size_t buffer_size;
  static LOOKUP_TYPE resbuf;
  LOOKUP_TYPE *result;
#ifdef NEED_H_ERRNO
  int h_errno_tmp = 0;
#endif

  /* Get lock.  */
  __libc_lock_lock (lock);

  if (buffer == NULL)
    {
      buffer_size = BUFLEN;
      buffer = (char *) malloc (buffer_size);
    }

#ifdef HANDLE_DIGITS_DOTS
  if (buffer != NULL)
    {
      if (__nss_hostname_digits_dots (name, &resbuf, &buffer,
				      &buffer_size, 0, &result, NULL, AF_VAL,
				      H_ERRNO_VAR_P))
	goto done;
    }
#endif

  while (buffer != NULL
	 && (INTERNAL (REENTRANT_NAME) (ADD_VARIABLES, &resbuf, buffer,
					buffer_size, &result H_ERRNO_VAR)
	     == ERANGE)
#ifdef NEED_H_ERRNO
	 && h_errno_tmp == NETDB_INTERNAL
#endif
	 )
    {
      char *new_buf;
      buffer_size *= 2;
      new_buf = (char *) realloc (buffer, buffer_size);
      if (new_buf == NULL)
	{
	  /* We are out of memory.  Free the current buffer so that the
	     process gets a chance for a normal termination.  */
	  free (buffer);
	  __set_errno (ENOMEM);
	}
      buffer = new_buf;
    }

  if (buffer == NULL)
    result = NULL;

#ifdef HANDLE_DIGITS_DOTS
done:
#endif
  /* Release lock.  */
  __libc_lock_unlock (lock);

#ifdef NEED_H_ERRNO
  if (h_errno_tmp != 0)
    __set_h_errno (h_errno_tmp);
#endif

  return result;
}