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; }
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; }
/* 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; }
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; }
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; }
/* 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; }
/* 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; }
/* 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; }
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); } }
/* 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; }
/* 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; }
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; }
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; }
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; }
/* 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; }
/* 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; }
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); } }
/* 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); }
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; }
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; }
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; }
/* 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; }
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; }
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); }
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; }
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; }
/* 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; }
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); }
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; }
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; }