_start (void) { char *buf = NULL; size_t bufsz = 0; while (__getdelim (&buf, &bufsz, '\n', stdin) > 0) { char *p = buf; eval (&p); } exit (0); }
/* Like getdelim, but always looks for a newline. */ ssize_t __getline (char **lineptr, size_t *n, FILE *stream) { return __getdelim (lineptr, n, '\n', stream); }
extern __inline __attribute__ ((__gnu_inline__)) __ssize_t getline (char **__lineptr, size_t *__n, FILE *__stream) { return __getdelim (__lineptr, __n, '\n', __stream); }
* Get an input line. * This now uses getdelim(3) for a code reduction. * The upside is that strings are now always NULL terminated, but relying * on this is non portable - better to use the POSIX getdelim(3) function. */ char * __fgetstr(FILE *__restrict fp, size_t *__restrict lenp, int sep) { char *p; size_t size; _DIAGASSERT(fp != NULL); _DIAGASSERT(lenp != NULL); p = (char *)fp->_lb._base; size = fp->_lb._size; *lenp = __getdelim(&p, &size, sep, fp); /* The struct size variable is only an int ..... */ if (size > INT_MAX) { fp->_lb._size = INT_MAX; errno = EOVERFLOW; goto error; } fp->_lb._size = (int)size; if (*lenp < SIZE_MAX) return p; error: *lenp = 0; return NULL; }
/* Read the next configuration file. */ static void internal_function read_conf_file (const char *filename, const char *directory, size_t dir_len, void **modules, size_t *nmodules) { FILE *fp = fopen (filename, "r"); char *line = NULL; size_t line_len = 0; static int modcounter; /* Don't complain if a file is not present or readable, simply silently ignore it. */ if (fp == NULL) return; /* No threads reading from this stream. */ __fsetlocking (fp, FSETLOCKING_BYCALLER); /* Process the known entries of the file. Comments start with `#' and end with the end of the line. Empty lines are ignored. */ while (!feof_unlocked (fp)) { char *rp, *endp, *word; ssize_t n = __getdelim (&line, &line_len, '\n', fp); if (n < 0) /* An error occurred. */ break; rp = line; /* Terminate the line (excluding comments or newline) by an NUL byte to simplify the following code. */ endp = strchr (rp, '#'); if (endp != NULL) *endp = '\0'; else if (rp[n - 1] == '\n') rp[n - 1] = '\0'; while (__isspace_l (*rp, &_nl_C_locobj)) ++rp; /* If this is an empty line go on with the next one. */ if (rp == endp) continue; word = rp; while (*rp != '\0' && !__isspace_l (*rp, &_nl_C_locobj)) ++rp; if (rp - word == sizeof ("alias") - 1 && memcmp (word, "alias", sizeof ("alias") - 1) == 0) add_alias (rp, *modules); else if (rp - word == sizeof ("module") - 1 && memcmp (word, "module", sizeof ("module") - 1) == 0) add_module (rp, directory, dir_len, modules, nmodules, modcounter++); /* else */ /* Otherwise ignore the line. */ } free (line); fclose (fp); }
ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream) { return __getdelim(lineptr, n, delim, stream); }
int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr) { pthread_handle handle = thread_handle (thread); pthread_descr descr; int ret = 0; if (handle == NULL) return ENOENT; descr = handle->h_descr; attr->__detachstate = (descr->p_detached ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE); attr->__schedpolicy = __sched_getscheduler (descr->p_pid); if (attr->__schedpolicy == -1) return errno; if (__sched_getparam (descr->p_pid, (struct sched_param *) &attr->__schedparam) != 0) return errno; attr->__inheritsched = descr->p_inheritsched; attr->__scope = PTHREAD_SCOPE_SYSTEM; #ifdef _STACK_GROWS_DOWN # ifdef USE_TLS attr->__stacksize = descr->p_stackaddr - (char *)descr->p_guardaddr - descr->p_guardsize; # else attr->__stacksize = (char *)(descr + 1) - (char *)descr->p_guardaddr - descr->p_guardsize; # endif #else # ifdef USE_TLS attr->__stacksize = (char *)descr->p_guardaddr - descr->p_stackaddr; # else attr->__stacksize = (char *)descr->p_guardaddr - (char *)descr; # endif #endif attr->__guardsize = descr->p_guardsize; attr->__stackaddr_set = descr->p_userstack; #ifdef NEED_SEPARATE_REGISTER_STACK if (descr->p_userstack == 0) attr->__stacksize *= 2; /* XXX This is awkward. The guard pages are in the middle of the two stacks. We must count the guard size in the stack size since otherwise the range of the stack area cannot be computed. */ attr->__stacksize += attr->__guardsize; #endif #ifdef USE_TLS attr->__stackaddr = descr->p_stackaddr; #else # ifndef _STACK_GROWS_UP attr->__stackaddr = (char *)(descr + 1); # else attr->__stackaddr = (char *)descr; # endif #endif #ifdef USE_TLS if (attr->__stackaddr == NULL) #else if (descr == &__pthread_initial_thread) #endif { /* Stack size limit. */ struct rlimit rl; /* The safest way to get the top of the stack is to read /proc/self/maps and locate the line into which __libc_stack_end falls. */ FILE *fp = fopen ("/proc/self/maps", "rc"); if (fp == NULL) ret = errno; /* We need the limit of the stack in any case. */ else if (getrlimit (RLIMIT_STACK, &rl) != 0) ret = errno; else { /* We need no locking. */ __fsetlocking (fp, FSETLOCKING_BYCALLER); /* Until we found an entry (which should always be the case) mark the result as a failure. */ ret = ENOENT; char *line = NULL; size_t linelen = 0; uintptr_t last_to = 0; while (! feof_unlocked (fp)) { if (__getdelim (&line, &linelen, '\n', fp) <= 0) break; uintptr_t from; uintptr_t to; if (sscanf (line, "%" SCNxPTR "-%" SCNxPTR, &from, &to) != 2) continue; if (from <= (uintptr_t) __libc_stack_end && (uintptr_t) __libc_stack_end < to) { /* Found the entry. Now we have the info we need. */ attr->__stacksize = rl.rlim_cur; #ifdef _STACK_GROWS_UP /* Don't check to enforce a limit on the __stacksize */ attr->__stackaddr = (void *) from; #else attr->__stackaddr = (void *) to; /* The limit might be too high. */ if ((size_t) attr->__stacksize > (size_t) attr->__stackaddr - last_to) attr->__stacksize = (size_t) attr->__stackaddr - last_to; #endif /* We succeed and no need to look further. */ ret = 0; break; } last_to = to; } fclose (fp); free (line); } } return 0; }