static char * getttyname (int fd, dev_t mydev, ino_t myino, int save, int *dostat) { static const char dev[] = "/dev"; static size_t namelen; struct stat st; DIR *dirstream; struct dirent *d; dirstream = __opendir (dev); if (dirstream == NULL) { *dostat = -1; return NULL; } while ((d = __readdir (dirstream)) != NULL) if (((ino_t) d->d_fileno == myino || *dostat) && strcmp (d->d_name, "stdin") && strcmp (d->d_name, "stdout") && strcmp (d->d_name, "stderr")) { size_t dlen = _D_ALLOC_NAMLEN (d); if (sizeof (dev) + dlen > namelen) { free (getttyname_name); namelen = 2 * (sizeof (dev) + dlen); /* Big enough. */ getttyname_name = malloc (namelen); if (! getttyname_name) { *dostat = -1; /* Perhaps it helps to free the directory stream buffer. */ (void) __closedir (dirstream); return NULL; } *((char *) __mempcpy (getttyname_name, dev, sizeof (dev) - 1)) = '/'; } (void) __mempcpy (&getttyname_name[sizeof (dev)], d->d_name, dlen); if (stat (getttyname_name, &st) == 0 #ifdef _STATBUF_ST_RDEV && S_ISCHR (st.st_mode) && st.st_rdev == mydev #else && (ino_t) d->d_fileno == myino && st.st_dev == mydev #endif ) { (void) __closedir (dirstream); __ttyname = getttyname_name; __set_errno (save); return getttyname_name; } } (void) __closedir (dirstream); __set_errno (save); return NULL; }
static void msort_with_tmp (void *b, size_t n, size_t s, __compar_fn_t cmp, char *t) { char *tmp; char *b1, *b2; size_t n1, n2; if (n <= 1) return; n1 = n / 2; n2 = n - n1; b1 = b; b2 = (char *) b + (n1 * s); msort_with_tmp (b1, n1, s, cmp, t); msort_with_tmp (b2, n2, s, cmp, t); tmp = t; if (s == OPSIZ && (b1 - (char *) 0) % OPSIZ == 0) /* We are operating on aligned words. Use direct word stores. */ while (n1 > 0 && n2 > 0) { if ((*cmp) (b1, b2) <= 0) { --n1; *((op_t *) tmp)++ = *((op_t *) b1)++; } else { --n2; *((op_t *) tmp)++ = *((op_t *) b2)++; } } else while (n1 > 0 && n2 > 0) { if ((*cmp) (b1, b2) <= 0) { tmp = (char *) __mempcpy (tmp, b1, s); b1 += s; --n1; } else { tmp = (char *) __mempcpy (tmp, b2, s); b2 += s; --n2; } } if (n1 > 0) memcpy (tmp, b1, n1 * s); memcpy (b, t, (n - n2) * s); }
static _IO_size_t _IO_file_xsgetn_mmap (_IO_FILE *fp, void *data, _IO_size_t n) { _IO_size_t have; char *read_ptr = fp->_IO_read_ptr; char *s = (char *) data; have = fp->_IO_read_end - fp->_IO_read_ptr; if (have < n) { if (__glibc_unlikely (_IO_in_backup (fp))) { #ifdef _LIBC s = __mempcpy (s, read_ptr, have); #else memcpy (s, read_ptr, have); s += have; #endif n -= have; _IO_switch_to_main_get_area (fp); read_ptr = fp->_IO_read_ptr; have = fp->_IO_read_end - fp->_IO_read_ptr; } if (have < n) { /* Check that we are mapping all of the file, in case it grew. */ if (__glibc_unlikely (mmap_remap_check (fp))) /* We punted mmap, so complete with the vanilla code. */ return s - (char *) data + _IO_XSGETN (fp, data, n); read_ptr = fp->_IO_read_ptr; have = fp->_IO_read_end - read_ptr; } } if (have < n) fp->_flags |= _IO_EOF_SEEN; if (have != 0) { have = MIN (have, n); #ifdef _LIBC s = __mempcpy (s, read_ptr, have); #else memcpy (s, read_ptr, have); s += have; #endif fp->_IO_read_ptr = read_ptr + have; } return s - (char *) data; }
/* Open shared memory object. This implementation assumes the shmfs implementation introduced in the late 2.3.x kernel series to be available. Normally the filesystem will be mounted at /dev/shm but we fall back on searching for the actual mount point should opening such a file fail. */ int shm_open (const char *name, int oflag, mode_t mode) { size_t namelen; char *fname; int fd; /* Determine where the shmfs is mounted. */ __libc_once (once, where_is_shmfs); /* If we don't know the mount points there is nothing we can do. Ever. */ if (mountpoint.dir == NULL) { __set_errno (ENOSYS); return -1; } /* Construct the filename. */ while (name[0] == '/') ++name; namelen = strlen (name); /* Validate the filename. */ if (name[0] == '\0' || namelen > NAME_MAX || strchr (name, '/') != NULL) { __set_errno (EINVAL); return -1; } fname = (char *) alloca (mountpoint.dirlen + namelen + 1); __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen), name, namelen + 1); /* And get the file descriptor. XXX Maybe we should test each descriptor whether it really is for a file on the shmfs. If this is what should be done the whole function should be revamped since we can determine whether shmfs is available while trying to open the file, all in one turn. */ fd = open (fname, oflag | O_CLOEXEC | O_NOFOLLOW, mode); if (fd == -1 && __glibc_unlikely (errno == EISDIR)) /* It might be better to fold this error with EINVAL since directory names are just another example for unsuitable shared object names and the standard does not mention EISDIR. */ __set_errno (EINVAL); return fd; }
nis_name nis_leaf_of_r (const_nis_name name, char *buffer, size_t buflen) { size_t i = 0; buffer[0] = '\0'; while (name[i] != '.' && name[i] != '\0') i++; if (i > buflen - 1) { __set_errno (ERANGE); return NULL; } if (i > 0) { if ((size_t)i >= buflen) { __set_errno (ERANGE); return NULL; } *((char *) __mempcpy (buffer, name, i)) = '\0'; } return buffer; }
nis_name nis_name_of_r (const_nis_name name, char *buffer, size_t buflen) { char *local_domain; int diff; local_domain = nis_local_directory (); diff = strlen (name) - strlen (local_domain); if (diff <= 0) return NULL; if (strcmp (&name[diff], local_domain) != 0) return NULL; if ((size_t) diff >= buflen) { __set_errno (ERANGE); return NULL; } *((char *) __mempcpy (buffer, name, diff - 1)) = '\0'; if (diff - 1 == 0) return NULL; return buffer; }
static _IO_size_t _IO_obstack_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n) { struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack; if (fp->_IO_write_ptr + n > fp->_IO_write_end) { int size; /* We need some more memory. First shrink the buffer to the space we really currently need. */ obstack_blank_fast (obstack, fp->_IO_write_ptr - fp->_IO_write_end); /* Now grow for N bytes, and put the data there. */ obstack_grow (obstack, data, n); /* Setup the buffer pointers again. */ fp->_IO_write_base = obstack_base (obstack); fp->_IO_write_ptr = obstack_next_free (obstack); size = obstack_room (obstack); fp->_IO_write_end = fp->_IO_write_ptr + size; /* Now allocate the rest of the current chunk. */ obstack_blank_fast (obstack, size); } else fp->_IO_write_ptr = __mempcpy (fp->_IO_write_ptr, data, n); return n; }
static int internal_function find_module (const char *directory, const char *filename, struct __gconv_step *result) { size_t dirlen = strlen (directory); size_t fnamelen = strlen (filename) + 1; char fullname[dirlen + fnamelen]; int status = __GCONV_NOCONV; memcpy (__mempcpy (fullname, directory, dirlen), filename, fnamelen); result->__shlib_handle = __gconv_find_shlib (fullname); if (result->__shlib_handle != NULL) { status = __GCONV_OK; result->__modname = NULL; result->__fct = result->__shlib_handle->fct; result->__init_fct = result->__shlib_handle->init_fct; result->__end_fct = result->__shlib_handle->end_fct; /* These settings can be overridden by the init function. */ result->__btowc_fct = NULL; result->__data = NULL; /* Call the init function. */ if (result->__init_fct != NULL) status = DL_CALL_FCT (result->__init_fct, (result)); } return status; }
/* Open a master pseudo terminal and return its file descriptor. */ int __getpt (void) { char buf[sizeof (_PATH_PTY) + 2]; const char *p, *q; char *s; s = __mempcpy (buf, _PATH_PTY, sizeof (_PATH_PTY) - 1); /* s[0] and s[1] will be filled in the loop. */ s[2] = '\0'; for (p = __libc_ptyname1; *p != '\0'; ++p) { s[0] = *p; for (q = __libc_ptyname2; *q != '\0'; ++q) { int fd; s[1] = *q; fd = __open (buf, O_RDWR); if (fd != -1) return fd; if (errno == ENOENT) return -1; } } __set_errno (ENOENT); return -1; }
const char * _dl_get_origin (void) { char linkval[PATH_MAX]; char *result; int len; INTERNAL_SYSCALL_DECL (err); len = INTERNAL_SYSCALL (readlinkat, err, 4, AT_FDCWD, "/proc/self/exe", linkval, sizeof (linkval)); if (! INTERNAL_SYSCALL_ERROR_P (len, err) && len > 0 && linkval[0] != '[') { /* We can use this value. */ assert (linkval[0] == '/'); while (len > 1 && linkval[len - 1] != '/') --len; result = (char *) malloc (len + 1); if (result == NULL) result = (char *) -1; else if (len == 1) memcpy (result, "/", 2); else *((char *) __mempcpy (result, linkval, len - 1)) = '\0'; } else { result = (char *) -1; /* We use the environment variable LD_ORIGIN_PATH. If it is set make a copy and strip out trailing slashes. */ if (GLRO(dl_origin_path) != NULL) { size_t len = strlen (GLRO(dl_origin_path)); result = (char *) malloc (len + 1); if (result == NULL) result = (char *) -1; else { char *cp = __mempcpy (result, GLRO(dl_origin_path), len); while (cp > result + 1 && cp[-1] == '/') --cp; *cp = '\0'; } } } return result; }
internal_function attribute_compat_text_section getttyname (const char *dev, dev_t mydev, ino64_t myino, int save, int *dostat) { static size_t namelen; struct stat64 st; DIR *dirstream; struct dirent64 *d; size_t devlen = strlen (dev) + 1; dirstream = __opendir (dev); if (dirstream == NULL) { *dostat = -1; return NULL; } while ((d = __readdir64 (dirstream)) != NULL) if ((d->d_fileno == myino || *dostat) && strcmp (d->d_name, "stdin") && strcmp (d->d_name, "stdout") && strcmp (d->d_name, "stderr")) { size_t dlen = _D_ALLOC_NAMLEN (d); if (devlen + dlen > namelen) { free (getttyname_name); namelen = 2 * (devlen + dlen); /* Big enough. */ getttyname_name = malloc (namelen); if (! getttyname_name) { *dostat = -1; /* Perhaps it helps to free the directory stream buffer. */ (void) __closedir (dirstream); return NULL; } *((char *) __mempcpy (getttyname_name, dev, devlen - 1)) = '/'; } memcpy (&getttyname_name[devlen], d->d_name, dlen); if (__xstat64 (_STAT_VER, getttyname_name, &st) == 0 #ifdef _STATBUF_ST_RDEV && S_ISCHR (st.st_mode) && st.st_rdev == mydev #else && d->d_fileno == myino && st.st_dev == mydev #endif ) { (void) __closedir (dirstream); #if 0 __ttyname = getttyname_name; #endif __set_errno (save); return getttyname_name; } } (void) __closedir (dirstream); __set_errno (save); return NULL; }
void * __mempcpy_chk (void *dstpp, const void *srcpp, size_t len, size_t dstlen) { if (__glibc_unlikely (dstlen < len)) __chk_fail (); return __mempcpy (dstpp, srcpp, len); }
wchar_t * __wmempcpy_chk (wchar_t *s1, const wchar_t *s2, size_t n, size_t ns1) { if (__glibc_unlikely (ns1 < n)) __chk_fail (); return (wchar_t *) __mempcpy ((char *) s1, (char *) s2, n * sizeof (wchar_t)); }
internal_function getttyname (const char *dev, dev_t mydev, ino64_t myino, int save) { static size_t namelen; struct stat64 st; DIR *dirstream; struct dirent *d; size_t devlen = strlen (dev) + 1; dirstream = __opendir (dev); if (dirstream == NULL) { return NULL; } while ((d = __readdir (dirstream)) != NULL) if (d->d_fileno == myino) { size_t dlen = _D_ALLOC_NAMLEN (d); if (devlen + dlen > namelen) { free (getttyname_name); namelen = 2 * (devlen + dlen); /* Big enough. */ getttyname_name = malloc (namelen); if (! getttyname_name) { /* Perhaps it helps to free the directory stream buffer. */ (void) __closedir (dirstream); return NULL; } } /* Always recopy dev since it may be master or slave. */ *((char *) __mempcpy (getttyname_name, dev, devlen - 1)) = '/'; memcpy (&getttyname_name[devlen], d->d_name, dlen); if (__xstat64 (_STAT_VER, getttyname_name, &st) == 0 #ifdef _STATBUF_ST_RDEV && S_ISCHR (st.st_mode) && st.st_rdev == mydev #else && d->d_fileno == myino && st.st_dev == mydev #endif ) { (void) __closedir (dirstream); #if 0 __ttyname = getttyname_name; #endif __set_errno (save); return getttyname_name; } } (void) __closedir (dirstream); __set_errno (save); return NULL; }
error_t _hurd_xattr_list (io_t port, void *buffer, size_t *size) { size_t total = 0; char *bufp = buffer; inline void add (const char *name, size_t len) { total += len; if (bufp != NULL && total <= *size) bufp = __mempcpy (bufp, name, len); }
/* Unlink a shared memory object. */ int shm_unlink (const char *name) { size_t namelen; char *fname; /* Determine where the shmfs is mounted. */ __libc_once (once, where_is_shmfs); if (mountpoint.dir == NULL) { /* We cannot find the shmfs. If `name' is really a shared memory object it must have been created by another process and we have no idea where that process found the mountpoint. */ __set_errno (ENOENT); return -1; } /* Construct the filename. */ while (name[0] == '/') ++name; namelen = strlen (name); /* Validate the filename. */ if (name[0] == '\0' || namelen > NAME_MAX || strchr (name, '/') != NULL) { __set_errno (ENOENT); return -1; } fname = (char *) alloca (mountpoint.dirlen + namelen + 1); __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen), name, namelen + 1); /* And remove the file. */ int ret = unlink (fname); if (ret < 0 && errno == EPERM) __set_errno (EACCES); return ret; }
/* Write data pointed by the buffers described by VECTOR, which is a vector of COUNT 'struct iovec's, to file descriptor FD. The data is written in the order specified. Operates just like 'write' (see <unistd.h>) except that the data are taken from VECTOR instead of a contiguous buffer. */ ssize_t __libc_writev (int fd, const struct iovec *vector, int count) { /* Find the total number of bytes to be written. */ size_t bytes = 0; for (int i = 0; i < count; ++i) { /* Check for ssize_t overflow. */ if (SSIZE_MAX - bytes < vector[i].iov_len) { __set_errno (EINVAL); return -1; } bytes += vector[i].iov_len; } /* Allocate a temporary buffer to hold the data. We should normally use alloca since it's faster and does not require synchronization with other threads. But we cannot if the amount of memory required is too large. */ char *buffer; char *malloced_buffer = NULL; if (__libc_use_alloca (bytes)) buffer = (char *) __alloca (bytes); else { malloced_buffer = buffer = (char *) malloc (bytes); if (buffer == NULL) /* XXX I don't know whether it is acceptable to try writing the data in chunks. Probably not so we just fail here. */ return -1; } /* Copy the data into BUFFER. */ size_t to_copy = bytes; char *bp = buffer; for (int i = 0; i < count; ++i) { size_t copy = MIN (vector[i].iov_len, to_copy); bp = __mempcpy ((void *) bp, (void *) vector[i].iov_base, copy); to_copy -= copy; if (to_copy == 0) break; } ssize_t bytes_written = __write (fd, buffer, bytes); free(malloced_buffer); return bytes_written; }
/* Remove shared memory object. */ int shm_unlink (const char *name) { size_t namelen; char *fname; /* Construct the filename. */ while (name[0] == '/') ++name; if (name[0] == '\0') { /* The name "/" is not supported. */ __set_errno (EINVAL); return -1; } namelen = strlen (name); fname = (char *) __alloca (sizeof SHMDIR - 1 + namelen + 1); __mempcpy (__mempcpy (fname, SHMDIR, sizeof SHMDIR - 1), name, namelen + 1); return unlink (name); }
internal_ucs4le_loop_unaligned (struct __gconv_step *step, struct __gconv_step_data *step_data, const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, size_t *irreversible) { const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; size_t n_convert = MIN (inend - inptr, outend - outptr) / 4; int result; # if __BYTE_ORDER == __BIG_ENDIAN /* Sigh, we have to do some real work. */ size_t cnt; for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4) { outptr[0] = inptr[3]; outptr[1] = inptr[2]; outptr[2] = inptr[1]; outptr[3] = inptr[0]; } *inptrp = inptr; *outptrp = outptr; # elif __BYTE_ORDER == __LITTLE_ENDIAN /* Simply copy the data. */ *inptrp = inptr + n_convert * 4; *outptrp = __mempcpy (outptr, inptr, n_convert * 4); # else # error "This endianess is not supported." # endif /* Determine the status. */ if (*inptrp == inend) result = __GCONV_EMPTY_INPUT; else if (*inptrp + 4 > inend) result = __GCONV_INCOMPLETE_INPUT; else { assert (*outptrp + 4 > outend); result = __GCONV_FULL_OUTPUT; } return result; }
/* Append BUF, of length BUF_LEN to *TO, of length *TO_LEN, reallocating and updating *TO & *TO_LEN appropriately. If an allocation error occurs, *TO's old value is freed, and *TO is set to 0. */ static void str_append (char **to, size_t *to_len, const char *buf, const size_t buf_len) { size_t new_len = *to_len + buf_len; char *new_to = realloc (*to, new_len + 1); if (new_to) { *((char *) __mempcpy (new_to + *to_len, buf, buf_len)) = '\0'; *to = new_to; *to_len = new_len; } else { free (*to); *to = 0; } }
nis_name nis_leaf_of_r (const_nis_name name, char *buffer, size_t buflen) { size_t i = 0; buffer[0] = '\0'; while (name[i] != '.' && name[i] != '\0') i++; if (__glibc_unlikely (i >= buflen)) { __set_errno (ERANGE); return NULL; } *((char *) __mempcpy (buffer, name, i)) = '\0'; return buffer; }
_IO_size_t _IO_default_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) { const char *s = (char *) data; _IO_size_t more = n; if (more <= 0) return 0; for (;;) { /* Space available. */ if (f->_IO_write_ptr < f->_IO_write_end) { _IO_size_t count = f->_IO_write_end - f->_IO_write_ptr; if (count > more) count = more; if (count > 20) { #ifdef _LIBC f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count); #else memcpy (f->_IO_write_ptr, s, count); f->_IO_write_ptr += count; #endif s += count; } else if (count) { char *p = f->_IO_write_ptr; _IO_ssize_t i; for (i = count; --i >= 0; ) *p++ = *s++; f->_IO_write_ptr = p; } more -= count; } if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF) break; more--; } return n - more; }
void _dl_exception_create (struct dl_exception *exception, const char *objname, const char *errstring) { if (objname == NULL) objname = ""; size_t len_objname = strlen (objname) + 1; size_t len_errstring = strlen (errstring) + 1; char *errstring_copy = malloc (len_objname + len_errstring); if (errstring_copy != NULL) { /* Make a copy of the object file name and the error string. */ exception->objname = memcpy (__mempcpy (errstring_copy, errstring, len_errstring), objname, len_objname); exception->errstring = errstring_copy; adjust_message_buffer (exception); } else oom_exception (exception); }
internal_ucs4_loop (struct __gconv_step *step, struct __gconv_step_data *step_data, const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, size_t *irreversible) { const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; size_t n_convert = MIN (inend - inptr, outend - outptr) / 4; int result; #if __BYTE_ORDER == __LITTLE_ENDIAN /* Sigh, we have to do some real work. */ size_t cnt; uint32_t *outptr32 = (uint32_t *) outptr; for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4) *outptr32++ = bswap_32 (*(const uint32_t *) inptr); *inptrp = inptr; *outptrp = (unsigned char *) outptr32; #elif __BYTE_ORDER == __BIG_ENDIAN /* Simply copy the data. */ *inptrp = inptr + n_convert * 4; *outptrp = __mempcpy (outptr, inptr, n_convert * 4); #else # error "This endianess is not supported." #endif /* Determine the status. */ if (*inptrp == inend) result = __GCONV_EMPTY_INPUT; else if (*outptrp + 4 > outend) result = __GCONV_FULL_OUTPUT; else result = __GCONV_INCOMPLETE_INPUT; return result; }
_IO_size_t _IO_default_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) { _IO_size_t more = n; char *s = (char*) data; for (;;) { /* Data available. */ if (fp->_IO_read_ptr < fp->_IO_read_end) { _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr; if (count > more) count = more; if (count > 20) { #ifdef _LIBC s = __mempcpy (s, fp->_IO_read_ptr, count); #else memcpy (s, fp->_IO_read_ptr, count); s += count; #endif fp->_IO_read_ptr += count; } else if (count) { char *p = fp->_IO_read_ptr; int i = (int) count; while (--i >= 0) *s++ = *p++; fp->_IO_read_ptr = p; } more -= count; } if (more == 0 || __underflow (fp) == EOF) break; } return n - more; }
const char * _dl_get_origin (void) { char *result = (char *) -1; /* We use the environment variable LD_ORIGIN_PATH. If it is set make a copy and strip out trailing slashes. */ if (GLRO(dl_origin_path) != NULL) { size_t len = strlen (GLRO(dl_origin_path)); result = (char *) malloc (len + 1); if (result == NULL) result = (char *) -1; else { char *cp = __mempcpy (result, GLRO(dl_origin_path), len); while (cp > result + 1 && cp[-1] == '/') --cp; *cp = '\0'; } } return result; }
/* Return a string describing the errno code in ERRNUM. */ char * __strerror_r (int errnum, char *buf, size_t buflen) { if (__builtin_expect (errnum < 0 || errnum >= _sys_nerr_internal || _sys_errlist_internal[errnum] == NULL, 0)) { /* Buffer we use to print the number in. For a maximum size for `int' of 8 bytes we never need more than 20 digits. */ char numbuf[21]; const char *unk = _("Unknown error "); size_t unklen = strlen (unk); char *p, *q; bool negative = errnum < 0; numbuf[20] = '\0'; p = _itoa_word (abs (errnum), &numbuf[20], 10, 0); /* Now construct the result while taking care for the destination buffer size. */ q = __mempcpy (buf, unk, MIN (unklen, buflen)); if (negative && unklen < buflen) { *q++ = '-'; ++unklen; } if (unklen < buflen) memcpy (q, p, MIN ((size_t) (&numbuf[21] - p), buflen - unklen)); /* Terminate the string in any case. */ if (buflen > 0) buf[buflen - 1] = '\0'; return buf; } return (char *) _(_sys_errlist_internal[errnum]); }
static void exchange (char **argv, struct _getopt_data *d) { int bottom = d->__first_nonopt; int middle = d->__last_nonopt; int top = d->optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ #if defined _LIBC && defined USE_NONOPTION_FLAGS /* First make sure the handling of the '__getopt_nonoption_flags' string can work normally. Our top argument must be in the range of the string. */ if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len) { /* We must extend the array. The user plays games with us and presents new arguments. */ char *new_str = malloc (top + 1); if (new_str == NULL) d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0; else { memset (__mempcpy (new_str, __getopt_nonoption_flags, d->__nonoption_flags_max_len), '\0', top + 1 - d->__nonoption_flags_max_len); d->__nonoption_flags_max_len = top + 1; __getopt_nonoption_flags = new_str; } } #endif while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; SWAP_FLAGS (bottom + i, middle + i); } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ d->__first_nonopt += (d->optind - d->__last_nonopt); d->__last_nonopt = d->optind; }
static void msort_with_tmp (const struct msort_param *p, void *b, size_t n) { char *b1, *b2; size_t n1, n2; if (n <= 1) return; n1 = n / 2; n2 = n - n1; b1 = b; b2 = (char *) b + (n1 * p->s); msort_with_tmp (p, b1, n1); msort_with_tmp (p, b2, n2); char *tmp = p->t; const size_t s = p->s; __compar_d_fn_t cmp = p->cmp; void *arg = p->arg; switch (p->var) { case 0: while (n1 > 0 && n2 > 0) { if ((*cmp) (b1, b2, arg) <= 0) { *(uint32_t *) tmp = *(uint32_t *) b1; b1 += sizeof (uint32_t); --n1; } else { *(uint32_t *) tmp = *(uint32_t *) b2; b2 += sizeof (uint32_t); --n2; } tmp += sizeof (uint32_t); } break; case 1: while (n1 > 0 && n2 > 0) { if ((*cmp) (b1, b2, arg) <= 0) { *(uint64_t *) tmp = *(uint64_t *) b1; b1 += sizeof (uint64_t); --n1; } else { *(uint64_t *) tmp = *(uint64_t *) b2; b2 += sizeof (uint64_t); --n2; } tmp += sizeof (uint64_t); } break; case 2: while (n1 > 0 && n2 > 0) { unsigned long *tmpl = (unsigned long *) tmp; unsigned long *bl; tmp += s; if ((*cmp) (b1, b2, arg) <= 0) { bl = (unsigned long *) b1; b1 += s; --n1; } else { bl = (unsigned long *) b2; b2 += s; --n2; } while (tmpl < (unsigned long *) tmp) *tmpl++ = *bl++; } break; case 3: while (n1 > 0 && n2 > 0) { if ((*cmp) (*(const void **) b1, *(const void **) b2, arg) <= 0) { *(void **) tmp = *(void **) b1; b1 += sizeof (void *); --n1; } else { *(void **) tmp = *(void **) b2; b2 += sizeof (void *); --n2; } tmp += sizeof (void *); } break; default: while (n1 > 0 && n2 > 0) { if ((*cmp) (b1, b2, arg) <= 0) { tmp = (char *) __mempcpy (tmp, b1, s); b1 += s; --n1; } else { tmp = (char *) __mempcpy (tmp, b2, s); b2 += s; --n2; } } break; } if (n1 > 0) memcpy (tmp, b1, n1 * s); memcpy (b, p->t, (n - n2) * s); }
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); }