Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/include/libbb.h


Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/include/libbb.h

    r1772 r2725  
    44 *
    55 * Based in part on code from sash, Copyright (c) 1999 by David I. Bell
    6  * Permission has been granted to redistribute this code under the GPL.
     6 * Permission has been granted to redistribute this code under GPL.
    77 *
    8  * Licensed under the GPL version 2, see the file LICENSE in this tarball.
     8 * Licensed under GPLv2, see file LICENSE in this source tree.
    99 */
    10 #ifndef __LIBBUSYBOX_H__
    11 #define __LIBBUSYBOX_H__    1
     10#ifndef LIBBB_H
     11#define LIBBB_H 1
    1212
    1313#include "platform.h"
     
    1818#include <fcntl.h>
    1919#include <inttypes.h>
    20 #include <mntent.h>
    2120#include <netdb.h>
    2221#include <setjmp.h>
    2322#include <signal.h>
     23#include <stdint.h>
    2424#include <stdio.h>
    2525#include <stdlib.h>
     
    2727#include <stddef.h>
    2828#include <string.h>
    29 /* #include <strings.h> - said to be obsolete */
     29#include <sys/poll.h>
    3030#include <sys/ioctl.h>
    3131#include <sys/mman.h>
    3232#include <sys/socket.h>
    3333#include <sys/stat.h>
    34 #include <sys/statfs.h>
    3534#include <sys/time.h>
    3635#include <sys/types.h>
     
    3938#include <time.h>
    4039#include <unistd.h>
    41 #include <utime.h>
    42 
     40#include <sys/param.h>
     41#ifdef HAVE_MNTENT_H
     42# include <mntent.h>
     43#endif
     44#ifdef HAVE_SYS_STATFS_H
     45# include <sys/statfs.h>
     46#endif
    4347#if ENABLE_SELINUX
    44 #include <selinux/selinux.h>
    45 #include <selinux/context.h>
    46 #endif
    47 
     48# include <selinux/selinux.h>
     49# include <selinux/context.h>
     50# include <selinux/flask.h>
     51# include <selinux/av_permissions.h>
     52#endif
    4853#if ENABLE_LOCALE_SUPPORT
    49 #include <locale.h>
    50 #else
    51 #define setlocale(x,y) ((void)0)
    52 #endif
    53 
    54 #include "pwd_.h"
    55 #include "grp_.h"
    56 /* ifdef it out, because it may include <shadow.h> */
    57 /* and we may not even _have_ <shadow.h>! */
     54# include <locale.h>
     55#else
     56# define setlocale(x,y) ((void)0)
     57#endif
     58#ifdef DMALLOC
     59# include <dmalloc.h>
     60#endif
     61#include <pwd.h>
     62#include <grp.h>
    5863#if ENABLE_FEATURE_SHADOWPASSWDS
    59 #include "shadow_.h"
    60 #endif
    61 
    62 /* Try to pull in PATH_MAX */
    63 #include <limits.h>
    64 #include <sys/param.h>
    65 #ifndef PATH_MAX
    66 #define PATH_MAX 256
    67 #endif
    68 
    69 /* Tested to work correctly (IIRC :]) */
    70 #define MAXINT(T) (T)( \
    71     ((T)-1) > 0 \
    72     ? (T)-1 \
    73     : (T)~((T)1 << (sizeof(T)*8-1)) \
    74     )
    75 
    76 #define MININT(T) (T)( \
    77     ((T)-1) > 0 \
    78     ? (T)0 \
    79     : ((T)1 << (sizeof(T)*8-1)) \
    80     )
    81 
    82 /* Large file support */
    83 /* Note that CONFIG_LFS forces bbox to be built with all common ops
    84  * (stat, lseek etc) mapped to "largefile" variants by libc.
    85  * Practically it means that open() automatically has O_LARGEFILE added
    86  * and all filesize/file_offset parameters and struct members are "large"
    87  * (in today's world - signed 64bit). For full support of large files,
    88  * we need a few helper #defines (below) and careful use of off_t
    89  * instead of int/ssize_t. No lseek64(), O_LARGEFILE etc necessary */
    90 #if ENABLE_LFS
    91 /* CONFIG_LFS is on */
    92 # if ULONG_MAX > 0xffffffff
    93 /* "long" is long enough on this system */
    94 #  define XATOOFF(a) xatoul_range(a, 0, LONG_MAX)
    95 /* usage: sz = BB_STRTOOFF(s, NULL, 10); if (errno || sz < 0) die(); */
    96 #  define BB_STRTOOFF bb_strtoul
    97 #  define STRTOOFF strtoul
    98 /* usage: printf("size: %"OFF_FMT"d (%"OFF_FMT"x)\n", sz, sz); */
    99 #  define OFF_FMT "l"
    100 # else
    101 /* "long" is too short, need "long long" */
    102 #  define XATOOFF(a) xatoull_range(a, 0, LLONG_MAX)
    103 #  define BB_STRTOOFF bb_strtoull
    104 #  define STRTOOFF strtoull
    105 #  define OFF_FMT "ll"
     64# if !ENABLE_USE_BB_SHADOW
     65/* If using busybox's shadow implementation, do not include the shadow.h
     66 * header as the toolchain may not provide it at all.
     67 */
     68#  include <shadow.h>
    10669# endif
    107 #else
    108 /* CONFIG_LFS is off */
    109 # if UINT_MAX == 0xffffffff
    110 /* While sizeof(off_t) == sizeof(int), off_t is typedef'ed to long anyway.
    111  * gcc will throw warnings on printf("%d", off_t). Crap... */
    112 #  define XATOOFF(a) xatoi_u(a)
    113 #  define BB_STRTOOFF bb_strtou
    114 #  define STRTOOFF strtol
    115 #  define OFF_FMT "l"
    116 # else
    117 #  define XATOOFF(a) xatoul_range(a, 0, LONG_MAX)
    118 #  define BB_STRTOOFF bb_strtoul
    119 #  define STRTOOFF strtol
    120 #  define OFF_FMT "l"
     70#endif
     71#if defined __FreeBSD__ || defined __OpenBSD__
     72# include <netinet/in.h>
     73# include <arpa/inet.h>
     74#elif defined __APPLE__
     75# include <netinet/in.h>
     76#else
     77# include <arpa/inet.h>
     78# if !defined(__socklen_t_defined) && !defined(_SOCKLEN_T_DECLARED)
     79/* We #define socklen_t *after* includes, otherwise we get
     80 * typedef redefinition errors from system headers
     81 * (in case "is it defined already" detection above failed)
     82 */
     83#  define socklen_t bb_socklen_t
     84   typedef unsigned socklen_t;
    12185# endif
    12286#endif
    123 /* scary. better ideas? (but do *test* them first!) */
    124 #define OFF_T_MAX  ((off_t)~((off_t)1 << (sizeof(off_t)*8-1)))
    125 
    126 /* Some useful definitions */
    127 #undef FALSE
    128 #define FALSE   ((int) 0)
    129 #undef TRUE
    130 #define TRUE    ((int) 1)
    131 #undef SKIP
    132 #define SKIP    ((int) 2)
    133 
    134 /* for mtab.c */
    135 #define MTAB_GETMOUNTPT '1'
    136 #define MTAB_GETDEVICE  '2'
    137 
    138 #define BUF_SIZE        8192
    139 #define EXPAND_ALLOC    1024
    140 
    141 /* Macros for min/max.  */
    142 #ifndef MIN
    143 #define MIN(a,b) (((a)<(b))?(a):(b))
    144 #endif
    145 
    146 #ifndef MAX
    147 #define MAX(a,b) (((a)>(b))?(a):(b))
    148 #endif
    149 
    150 /* buffer allocation schemes */
    151 #if ENABLE_FEATURE_BUFFERS_GO_ON_STACK
    152 #define RESERVE_CONFIG_BUFFER(buffer,len)  char buffer[len]
    153 #define RESERVE_CONFIG_UBUFFER(buffer,len) unsigned char buffer[len]
    154 #define RELEASE_CONFIG_BUFFER(buffer)      ((void)0)
    155 #else
    156 #if ENABLE_FEATURE_BUFFERS_GO_IN_BSS
    157 #define RESERVE_CONFIG_BUFFER(buffer,len)  static          char buffer[len]
    158 #define RESERVE_CONFIG_UBUFFER(buffer,len) static unsigned char buffer[len]
    159 #define RELEASE_CONFIG_BUFFER(buffer)      ((void)0)
    160 #else
    161 #define RESERVE_CONFIG_BUFFER(buffer,len)  char *buffer = xmalloc(len)
    162 #define RESERVE_CONFIG_UBUFFER(buffer,len) unsigned char *buffer = xmalloc(len)
    163 #define RELEASE_CONFIG_BUFFER(buffer)      free(buffer)
    164 #endif
    165 #endif
    166 
    167 
    168 #if defined(__GLIBC__)
    169 /* glibc uses __errno_location() to get a ptr to errno */
    170 /* We can just memorize it once - no multithreading in busybox :) */
    171 extern int *const bb_errno;
    172 #undef errno
    173 #define errno (*bb_errno)
    174 #endif
    175 
     87
     88
     89/* Some libc's forget to declare these, do it ourself */
     90
     91extern char **environ;
    17692#if defined(__GLIBC__) && __GLIBC__ < 2
    17793int vdprintf(int d, const char *format, va_list ap);
    17894#endif
    179 // This is declared here rather than #including <libgen.h> in order to avoid
    180 // confusing the two versions of basename.  See the dirname/basename man page
    181 // for details.
     95/* klogctl is in libc's klog.h, but we cheat and not #include that */
     96int klogctl(int type, char *b, int len);
     97/* This is declared here rather than #including <libgen.h> in order to avoid
     98 * confusing the two versions of basename.  See the dirname/basename man page
     99 * for details. */
     100#if !defined __FreeBSD__
    182101char *dirname(char *path);
     102#endif
    183103/* Include our own copy of struct sysinfo to avoid binary compatibility
    184104 * problems with Linux 2.4, which changed things.  Grumble, grumble. */
     
    197117    unsigned long freehigh;     /* Available high memory size */
    198118    unsigned int mem_unit;      /* Memory unit size in bytes */
    199     char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
     119    char _f[20 - 2 * sizeof(long) - sizeof(int)]; /* Padding: libc5 uses this.. */
    200120};
    201121int sysinfo(struct sysinfo* info);
    202 
    203 unsigned long long monotonic_us(void);
    204 unsigned monotonic_sec(void);
    205 
    206 extern void chomp(char *s);
    207 extern void trim(char *s);
    208 extern char *skip_whitespace(const char *);
    209 extern char *skip_non_whitespace(const char *);
     122#ifndef PATH_MAX
     123# define PATH_MAX 256
     124#endif
     125#ifndef BUFSIZ
     126# define BUFSIZ 4096
     127#endif
     128
     129
     130/* Make all declarations hidden (-fvisibility flag only affects definitions) */
     131/* (don't include system headers after this until corresponding pop!) */
     132PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
     133
     134
     135#if ENABLE_USE_BB_PWD_GRP
     136# include "pwd_.h"
     137# include "grp_.h"
     138#endif
     139#if ENABLE_FEATURE_SHADOWPASSWDS
     140# if ENABLE_USE_BB_SHADOW
     141#  include "shadow_.h"
     142# endif
     143#endif
     144
     145/* Tested to work correctly with all int types (IIRC :]) */
     146#define MAXINT(T) (T)( \
     147    ((T)-1) > 0 \
     148    ? (T)-1 \
     149    : (T)~((T)1 << (sizeof(T)*8-1)) \
     150    )
     151
     152#define MININT(T) (T)( \
     153    ((T)-1) > 0 \
     154    ? (T)0 \
     155    : ((T)1 << (sizeof(T)*8-1)) \
     156    )
     157
     158/* Large file support */
     159/* Note that CONFIG_LFS=y forces bbox to be built with all common ops
     160 * (stat, lseek etc) mapped to "largefile" variants by libc.
     161 * Practically it means that open() automatically has O_LARGEFILE added
     162 * and all filesize/file_offset parameters and struct members are "large"
     163 * (in today's world - signed 64bit). For full support of large files,
     164 * we need a few helper #defines (below) and careful use of off_t
     165 * instead of int/ssize_t. No lseek64(), O_LARGEFILE etc necessary */
     166#if ENABLE_LFS
     167/* CONFIG_LFS is on */
     168# if ULONG_MAX > 0xffffffff
     169/* "long" is long enough on this system */
     170typedef unsigned long uoff_t;
     171#  define XATOOFF(a) xatoul_range(a, 0, LONG_MAX)
     172/* usage: sz = BB_STRTOOFF(s, NULL, 10); if (errno || sz < 0) die(); */
     173#  define BB_STRTOOFF bb_strtoul
     174#  define STRTOOFF strtoul
     175/* usage: printf("size: %"OFF_FMT"d (%"OFF_FMT"x)\n", sz, sz); */
     176#  define OFF_FMT "l"
     177# else
     178/* "long" is too short, need "long long" */
     179typedef unsigned long long uoff_t;
     180#  define XATOOFF(a) xatoull_range(a, 0, LLONG_MAX)
     181#  define BB_STRTOOFF bb_strtoull
     182#  define STRTOOFF strtoull
     183#  define OFF_FMT "ll"
     184# endif
     185#else
     186/* CONFIG_LFS is off */
     187# if UINT_MAX == 0xffffffff
     188/* While sizeof(off_t) == sizeof(int), off_t is typedef'ed to long anyway.
     189 * gcc will throw warnings on printf("%d", off_t). Crap... */
     190typedef unsigned long uoff_t;
     191#  define XATOOFF(a) xatoi_positive(a)
     192#  define BB_STRTOOFF bb_strtou
     193#  define STRTOOFF strtol
     194#  define OFF_FMT "l"
     195# else
     196typedef unsigned long uoff_t;
     197#  define XATOOFF(a) xatoul_range(a, 0, LONG_MAX)
     198#  define BB_STRTOOFF bb_strtoul
     199#  define STRTOOFF strtol
     200#  define OFF_FMT "l"
     201# endif
     202#endif
     203/* scary. better ideas? (but do *test* them first!) */
     204#define OFF_T_MAX  ((off_t)~((off_t)1 << (sizeof(off_t)*8-1)))
     205
     206/* Some useful definitions */
     207#undef FALSE
     208#define FALSE   ((int) 0)
     209#undef TRUE
     210#define TRUE    ((int) 1)
     211#undef SKIP
     212#define SKIP    ((int) 2)
     213
     214/* for mtab.c */
     215#define MTAB_GETMOUNTPT '1'
     216#define MTAB_GETDEVICE  '2'
     217
     218#define BUF_SIZE        8192
     219#define EXPAND_ALLOC    1024
     220
     221/* Macros for min/max.  */
     222#ifndef MIN
     223#define MIN(a,b) (((a)<(b))?(a):(b))
     224#endif
     225
     226#ifndef MAX
     227#define MAX(a,b) (((a)>(b))?(a):(b))
     228#endif
     229
     230/* buffer allocation schemes */
     231#if ENABLE_FEATURE_BUFFERS_GO_ON_STACK
     232#define RESERVE_CONFIG_BUFFER(buffer,len)  char buffer[len]
     233#define RESERVE_CONFIG_UBUFFER(buffer,len) unsigned char buffer[len]
     234#define RELEASE_CONFIG_BUFFER(buffer)      ((void)0)
     235#else
     236#if ENABLE_FEATURE_BUFFERS_GO_IN_BSS
     237#define RESERVE_CONFIG_BUFFER(buffer,len)  static          char buffer[len]
     238#define RESERVE_CONFIG_UBUFFER(buffer,len) static unsigned char buffer[len]
     239#define RELEASE_CONFIG_BUFFER(buffer)      ((void)0)
     240#else
     241#define RESERVE_CONFIG_BUFFER(buffer,len)  char *buffer = xmalloc(len)
     242#define RESERVE_CONFIG_UBUFFER(buffer,len) unsigned char *buffer = xmalloc(len)
     243#define RELEASE_CONFIG_BUFFER(buffer)      free(buffer)
     244#endif
     245#endif
     246
     247#if defined(__GLIBC__)
     248/* glibc uses __errno_location() to get a ptr to errno */
     249/* We can just memorize it once - no multithreading in busybox :) */
     250extern int *const bb_errno;
     251#undef errno
     252#define errno (*bb_errno)
     253#endif
     254
     255#if !(ULONG_MAX > 0xffffffff)
     256/* Only 32-bit CPUs need this, 64-bit ones use inlined version */
     257uint64_t bb_bswap_64(uint64_t x) FAST_FUNC;
     258#endif
     259
     260unsigned long long monotonic_ns(void) FAST_FUNC;
     261unsigned long long monotonic_us(void) FAST_FUNC;
     262unsigned long long monotonic_ms(void) FAST_FUNC;
     263unsigned monotonic_sec(void) FAST_FUNC;
     264
     265extern void chomp(char *s) FAST_FUNC;
     266extern void trim(char *s) FAST_FUNC;
     267extern char *skip_whitespace(const char *) FAST_FUNC;
     268extern char *skip_non_whitespace(const char *) FAST_FUNC;
     269extern char *skip_dev_pfx(const char *tty_name) FAST_FUNC;
     270
     271extern char *strrstr(const char *haystack, const char *needle) FAST_FUNC;
    210272
    211273//TODO: supply a pointer to char[11] buffer (avoid statics)?
    212 extern const char *bb_mode_string(mode_t mode);
    213 extern int is_directory(const char *name, int followLinks, struct stat *statBuf);
    214 extern int remove_file(const char *path, int flags);
    215 extern int copy_file(const char *source, const char *dest, int flags);
     274extern const char *bb_mode_string(mode_t mode) FAST_FUNC;
     275extern int is_directory(const char *name, int followLinks, struct stat *statBuf) FAST_FUNC;
     276enum {  /* DO NOT CHANGE THESE VALUES!  cp.c, mv.c, install.c depend on them. */
     277    FILEUTILS_PRESERVE_STATUS = 1 << 0, /* -p */
     278    FILEUTILS_DEREFERENCE     = 1 << 1, /* !-d */
     279    FILEUTILS_RECUR           = 1 << 2, /* -R */
     280    FILEUTILS_FORCE           = 1 << 3, /* -f */
     281    FILEUTILS_INTERACTIVE     = 1 << 4, /* -i */
     282    FILEUTILS_MAKE_HARDLINK   = 1 << 5, /* -l */
     283    FILEUTILS_MAKE_SOFTLINK   = 1 << 6, /* -s */
     284    FILEUTILS_DEREF_SOFTLINK  = 1 << 7, /* -L */
     285    FILEUTILS_DEREFERENCE_L0  = 1 << 8, /* -H */
     286#if ENABLE_SELINUX
     287    FILEUTILS_PRESERVE_SECURITY_CONTEXT = 1 << 9, /* -c */
     288    FILEUTILS_SET_SECURITY_CONTEXT = 1 << 10,
     289#endif
     290};
     291#define FILEUTILS_CP_OPTSTR "pdRfilsLH" IF_SELINUX("c")
     292extern int remove_file(const char *path, int flags) FAST_FUNC;
     293/* NB: without FILEUTILS_RECUR in flags, it will basically "cat"
     294 * the source, not copy (unless "source" is a directory).
     295 * This makes "cp /dev/null file" and "install /dev/null file" (!!!)
     296 * work coreutils-compatibly. */
     297extern int copy_file(const char *source, const char *dest, int flags) FAST_FUNC;
     298
    216299enum {
    217300    ACTION_RECURSE        = (1 << 0),
     
    220303    ACTION_DEPTHFIRST     = (1 << 3),
    221304    /*ACTION_REVERSE      = (1 << 4), - unused */
    222 };
     305    ACTION_QUIET          = (1 << 5),
     306    ACTION_DANGLING_OK    = (1 << 6),
     307};
     308typedef uint8_t recurse_flags_t;
    223309extern int recursive_action(const char *fileName, unsigned flags,
    224     int (*fileAction) (const char *fileName, struct stat* statbuf, void* userData, int depth),
    225     int (*dirAction) (const char *fileName, struct stat* statbuf, void* userData, int depth),
    226     void* userData, unsigned depth);
    227 extern int device_open(const char *device, int mode);
    228 extern int get_console_fd(void);
    229 extern char *find_block_device(const char *path);
     310    int FAST_FUNC (*fileAction)(const char *fileName, struct stat* statbuf, void* userData, int depth),
     311    int FAST_FUNC (*dirAction)(const char *fileName, struct stat* statbuf, void* userData, int depth),
     312    void* userData, unsigned depth) FAST_FUNC;
     313extern int device_open(const char *device, int mode) FAST_FUNC;
     314enum { GETPTY_BUFSIZE = 16 }; /* more than enough for "/dev/ttyXXX" */
     315extern int xgetpty(char *line) FAST_FUNC;
     316extern int get_console_fd_or_die(void) FAST_FUNC;
     317extern void console_make_active(int fd, const int vt_num) FAST_FUNC;
     318extern char *find_block_device(const char *path) FAST_FUNC;
    230319/* bb_copyfd_XX print read/write errors and return -1 if they occur */
    231 extern off_t bb_copyfd_eof(int fd1, int fd2);
    232 extern off_t bb_copyfd_size(int fd1, int fd2, off_t size);
    233 extern void bb_copyfd_exact_size(int fd1, int fd2, off_t size);
     320extern off_t bb_copyfd_eof(int fd1, int fd2) FAST_FUNC;
     321extern off_t bb_copyfd_size(int fd1, int fd2, off_t size) FAST_FUNC;
     322extern void bb_copyfd_exact_size(int fd1, int fd2, off_t size) FAST_FUNC;
    234323/* "short" copy can be detected by return value < size */
    235324/* this helper yells "short read!" if param is not -1 */
    236 extern void complain_copyfd_and_die(off_t sz) ATTRIBUTE_NORETURN;
    237 extern char bb_process_escape_sequence(const char **ptr);
    238 /* TODO: sometimes modifies its parameter, which
    239  * makes it rather inconvenient at times: */
    240 extern char *bb_get_last_path_component(char *path);
    241 
    242 int ndelay_on(int fd);
    243 int ndelay_off(int fd);
    244 void xdup2(int, int);
    245 void xmove_fd(int, int);
    246 
    247 
    248 DIR *xopendir(const char *path);
    249 DIR *warn_opendir(const char *path);
    250 
    251 /* UNUSED: char *xmalloc_realpath(const char *path); */
    252 char *xmalloc_readlink(const char *path);
    253 char *xmalloc_readlink_or_warn(const char *path);
    254 char *xrealloc_getcwd_or_warn(char *cwd);
    255 
    256 
    257 //TODO: signal(sid, f) is the same? then why?
    258 extern void sig_catch(int,void (*)(int));
    259 //#define sig_ignore(s) (sig_catch((s), SIG_IGN))
    260 //#define sig_uncatch(s) (sig_catch((s), SIG_DFL))
    261 extern void sig_block(int);
    262 extern void sig_unblock(int);
    263 /* UNUSED: extern void sig_blocknone(void); */
    264 extern void sig_pause(void);
    265 
    266 
    267 void xsetgid(gid_t gid);
    268 void xsetuid(uid_t uid);
    269 void xchdir(const char *path);
    270 void xsetenv(const char *key, const char *value);
    271 void xunlink(const char *pathname);
    272 void xstat(const char *pathname, struct stat *buf);
    273 int xopen(const char *pathname, int flags);
    274 int xopen3(const char *pathname, int flags, int mode);
    275 int open_or_warn(const char *pathname, int flags);
    276 int open3_or_warn(const char *pathname, int flags, int mode);
    277 void xpipe(int filedes[2]);
    278 off_t xlseek(int fd, off_t offset, int whence);
    279 off_t fdlength(int fd);
    280 
    281 int xsocket(int domain, int type, int protocol);
    282 void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
    283 void xlisten(int s, int backlog);
    284 void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen);
     325extern void complain_copyfd_and_die(off_t sz) NORETURN FAST_FUNC;
     326extern char bb_process_escape_sequence(const char **ptr) FAST_FUNC;
     327char* strcpy_and_process_escape_sequences(char *dst, const char *src) FAST_FUNC;
     328/* xxxx_strip version can modify its parameter:
     329 * "/"        -> "/"
     330 * "abc"      -> "abc"
     331 * "abc/def"  -> "def"
     332 * "abc/def/" -> "def" !!
     333 */
     334extern char *bb_get_last_path_component_strip(char *path) FAST_FUNC;
     335/* "abc/def/" -> "" and it never modifies 'path' */
     336extern char *bb_get_last_path_component_nostrip(const char *path) FAST_FUNC;
     337
     338int ndelay_on(int fd) FAST_FUNC;
     339int ndelay_off(int fd) FAST_FUNC;
     340int close_on_exec_on(int fd) FAST_FUNC;
     341void xdup2(int, int) FAST_FUNC;
     342void xmove_fd(int, int) FAST_FUNC;
     343
     344
     345DIR *xopendir(const char *path) FAST_FUNC;
     346DIR *warn_opendir(const char *path) FAST_FUNC;
     347
     348char *xmalloc_realpath(const char *path) FAST_FUNC RETURNS_MALLOC;
     349char *xmalloc_readlink(const char *path) FAST_FUNC RETURNS_MALLOC;
     350char *xmalloc_readlink_or_warn(const char *path) FAST_FUNC RETURNS_MALLOC;
     351/* !RETURNS_MALLOC: it's a realloc-like function */
     352char *xrealloc_getcwd_or_warn(char *cwd) FAST_FUNC;
     353
     354char *xmalloc_follow_symlinks(const char *path) FAST_FUNC RETURNS_MALLOC;
     355
     356
     357enum {
     358    /* bb_signals(BB_FATAL_SIGS, handler) catches all signals which
     359     * otherwise would kill us, except for those resulting from bugs:
     360     * SIGSEGV, SIGILL, SIGFPE.
     361     * Other fatal signals not included (TODO?):
     362     * SIGBUS   Bus error (bad memory access)
     363     * SIGPOLL  Pollable event. Synonym of SIGIO
     364     * SIGPROF  Profiling timer expired
     365     * SIGSYS   Bad argument to routine
     366     * SIGTRAP  Trace/breakpoint trap
     367     *
     368     * The only known arch with some of these sigs not fitting
     369     * into 32 bits is parisc (SIGXCPU=33, SIGXFSZ=34, SIGSTKFLT=36).
     370     * Dance around with long long to guard against that...
     371     */
     372    BB_FATAL_SIGS = (int)(0
     373        + (1LL << SIGHUP)
     374        + (1LL << SIGINT)
     375        + (1LL << SIGTERM)
     376        + (1LL << SIGPIPE)   // Write to pipe with no readers
     377        + (1LL << SIGQUIT)   // Quit from keyboard
     378        + (1LL << SIGABRT)   // Abort signal from abort(3)
     379        + (1LL << SIGALRM)   // Timer signal from alarm(2)
     380        + (1LL << SIGVTALRM) // Virtual alarm clock
     381        + (1LL << SIGXCPU)   // CPU time limit exceeded
     382        + (1LL << SIGXFSZ)   // File size limit exceeded
     383        + (1LL << SIGUSR1)   // Yes kids, these are also fatal!
     384        + (1LL << SIGUSR2)
     385        + 0),
     386};
     387void bb_signals(int sigs, void (*f)(int)) FAST_FUNC;
     388/* Unlike signal() and bb_signals, sets handler with sigaction()
     389 * and in a way that while signal handler is run, no other signals
     390 * will be blocked; syscalls will not be restarted: */
     391void bb_signals_recursive_norestart(int sigs, void (*f)(int)) FAST_FUNC;
     392/* syscalls like read() will be interrupted with EINTR: */
     393void signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int)) FAST_FUNC;
     394/* syscalls like read() won't be interrupted (though select/poll will be): */
     395void signal_SA_RESTART_empty_mask(int sig, void (*handler)(int)) FAST_FUNC;
     396void wait_for_any_sig(void) FAST_FUNC;
     397void kill_myself_with_sig(int sig) NORETURN FAST_FUNC;
     398void sig_block(int sig) FAST_FUNC;
     399void sig_unblock(int sig) FAST_FUNC;
     400/* Will do sigaction(signum, act, NULL): */
     401int sigaction_set(int sig, const struct sigaction *act) FAST_FUNC;
     402/* SIG_BLOCK/SIG_UNBLOCK all signals: */
     403int sigprocmask_allsigs(int how) FAST_FUNC;
     404/* Standard handler which just records signo */
     405extern smallint bb_got_signal;
     406void record_signo(int signo); /* not FAST_FUNC! */
     407
     408
     409void xsetgid(gid_t gid) FAST_FUNC;
     410void xsetuid(uid_t uid) FAST_FUNC;
     411void xchdir(const char *path) FAST_FUNC;
     412void xchroot(const char *path) FAST_FUNC;
     413void xsetenv(const char *key, const char *value) FAST_FUNC;
     414void bb_unsetenv(const char *key) FAST_FUNC;
     415void bb_unsetenv_and_free(char *key) FAST_FUNC;
     416void xunlink(const char *pathname) FAST_FUNC;
     417void xstat(const char *pathname, struct stat *buf) FAST_FUNC;
     418void xfstat(int fd, struct stat *buf, const char *errmsg) FAST_FUNC;
     419int xopen(const char *pathname, int flags) FAST_FUNC;
     420int xopen_nonblocking(const char *pathname) FAST_FUNC;
     421int xopen3(const char *pathname, int flags, int mode) FAST_FUNC;
     422int open_or_warn(const char *pathname, int flags) FAST_FUNC;
     423int open3_or_warn(const char *pathname, int flags, int mode) FAST_FUNC;
     424int open_or_warn_stdin(const char *pathname) FAST_FUNC;
     425int xopen_stdin(const char *pathname) FAST_FUNC;
     426void xrename(const char *oldpath, const char *newpath) FAST_FUNC;
     427int rename_or_warn(const char *oldpath, const char *newpath) FAST_FUNC;
     428off_t xlseek(int fd, off_t offset, int whence) FAST_FUNC;
     429int xmkstemp(char *template) FAST_FUNC;
     430off_t fdlength(int fd) FAST_FUNC;
     431
     432uoff_t FAST_FUNC get_volume_size_in_bytes(int fd,
     433                const char *override,
     434                unsigned override_units,
     435                int extend);
     436
     437void xpipe(int filedes[2]) FAST_FUNC;
     438/* In this form code with pipes is much more readable */
     439struct fd_pair { int rd; int wr; };
     440#define piped_pair(pair)  pipe(&((pair).rd))
     441#define xpiped_pair(pair) xpipe(&((pair).rd))
     442
     443/* Useful for having small structure members/global variables */
     444typedef int8_t socktype_t;
     445typedef int8_t family_t;
     446struct BUG_too_small {
     447    char BUG_socktype_t_too_small[(0
     448            | SOCK_STREAM
     449            | SOCK_DGRAM
     450            | SOCK_RDM
     451            | SOCK_SEQPACKET
     452            | SOCK_RAW
     453            ) <= 127 ? 1 : -1];
     454    char BUG_family_t_too_small[(0
     455            | AF_UNSPEC
     456            | AF_INET
     457            | AF_INET6
     458            | AF_UNIX
     459#ifdef AF_PACKET
     460            | AF_PACKET
     461#endif
     462#ifdef AF_NETLINK
     463            | AF_NETLINK
     464#endif
     465            /* | AF_DECnet */
     466            /* | AF_IPX */
     467            ) <= 127 ? 1 : -1];
     468};
     469
     470
     471void parse_datestr(const char *date_str, struct tm *ptm) FAST_FUNC;
     472time_t validate_tm_time(const char *date_str, struct tm *ptm) FAST_FUNC;
     473
     474
     475int xsocket(int domain, int type, int protocol) FAST_FUNC;
     476void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) FAST_FUNC;
     477void xlisten(int s, int backlog) FAST_FUNC;
     478void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) FAST_FUNC;
    285479ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
    286                 socklen_t tolen);
     480                socklen_t tolen) FAST_FUNC;
    287481/* SO_REUSEADDR allows a server to rebind to an address that is already
    288482 * "in use" by old connections to e.g. previous server instance which is
     
    291485 * regardless of SO_REUSEADDR (unlike some other flavors of Unix).
    292486 * Turn it on before you call bind(). */
    293 void setsockopt_reuseaddr(int fd); /* On Linux this never fails. */
    294 int setsockopt_broadcast(int fd);
     487void setsockopt_reuseaddr(int fd) FAST_FUNC; /* On Linux this never fails. */
     488int setsockopt_broadcast(int fd) FAST_FUNC;
     489int setsockopt_bindtodevice(int fd, const char *iface) FAST_FUNC;
    295490/* NB: returns port in host byte order */
    296 unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port);
     491unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port) FAST_FUNC;
    297492typedef struct len_and_sockaddr {
    298493    socklen_t len;
     
    303498        struct sockaddr_in6 sin6;
    304499#endif
    305     };
     500    } u;
    306501} len_and_sockaddr;
    307502enum {
     503    LSA_LEN_SIZE = offsetof(len_and_sockaddr, u),
    308504    LSA_SIZEOF_SA = sizeof(
    309505        union {
     
    319515 * (lsa of correct size and lsa->sa.sa_family (AF_INET/AF_INET6))
    320516 * af == AF_UNSPEC will result in trying to create IPv6 socket,
    321  * and if kernel doesn't support it, IPv4.
     517 * and if kernel doesn't support it, fall back to IPv4.
     518 * This is useful if you plan to bind to resulting local lsa.
    322519 */
    323 int xsocket_type(len_and_sockaddr **lsap, USE_FEATURE_IPV6(int af,) int sock_type);
    324 int xsocket_stream(len_and_sockaddr **lsap);
     520#if ENABLE_FEATURE_IPV6
     521int xsocket_type(len_and_sockaddr **lsap, int af, int sock_type) FAST_FUNC;
     522#else
     523int xsocket_type(len_and_sockaddr **lsap, int sock_type) FAST_FUNC;
     524#define xsocket_type(lsap, af, sock_type) xsocket_type((lsap), (sock_type))
     525#endif
     526int xsocket_stream(len_and_sockaddr **lsap) FAST_FUNC;
    325527/* Create server socket bound to bindaddr:port. bindaddr can be NULL,
    326528 * numeric IP ("N.N.N.N") or numeric IPv6 address,
     
    328530 * Only if there is no suffix, port argument is used */
    329531/* NB: these set SO_REUSEADDR before bind */
    330 int create_and_bind_stream_or_die(const char *bindaddr, int port);
    331 int create_and_bind_dgram_or_die(const char *bindaddr, int port);
     532int create_and_bind_stream_or_die(const char *bindaddr, int port) FAST_FUNC;
     533int create_and_bind_dgram_or_die(const char *bindaddr, int port) FAST_FUNC;
    332534/* Create client TCP socket connected to peer:port. Peer cannot be NULL.
    333535 * Peer can be numeric IP ("N.N.N.N"), numeric IPv6 address or hostname,
    334536 * and can have ":PORT" suffix (for IPv6 use "[X:X:...:X]:PORT").
    335537 * If there is no suffix, port argument is used */
    336 int create_and_connect_stream_or_die(const char *peer, int port);
     538int create_and_connect_stream_or_die(const char *peer, int port) FAST_FUNC;
    337539/* Connect to peer identified by lsa */
    338 int xconnect_stream(const len_and_sockaddr *lsa);
     540int xconnect_stream(const len_and_sockaddr *lsa) FAST_FUNC;
     541/* Get local address of bound or accepted socket */
     542len_and_sockaddr *get_sock_lsa(int fd) FAST_FUNC RETURNS_MALLOC;
     543/* Get remote address of connected or accepted socket */
     544len_and_sockaddr *get_peer_lsa(int fd) FAST_FUNC RETURNS_MALLOC;
    339545/* Return malloc'ed len_and_sockaddr with socket address of host:port
    340546 * Currently will return IPv4 or IPv6 sockaddrs only
     
    342548 * UNIX socket address being returned, IPX sockaddr etc...
    343549 * On error does bb_error_msg and returns NULL */
    344 len_and_sockaddr* host2sockaddr(const char *host, int port);
     550len_and_sockaddr* host2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
    345551/* Version which dies on error */
    346 len_and_sockaddr* xhost2sockaddr(const char *host, int port);
    347 len_and_sockaddr* xdotted2sockaddr(const char *host, int port);
    348 #if ENABLE_FEATURE_IPV6
     552len_and_sockaddr* xhost2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
     553len_and_sockaddr* xdotted2sockaddr(const char *host, int port) FAST_FUNC RETURNS_MALLOC;
    349554/* Same, useful if you want to force family (e.g. IPv6) */
    350 len_and_sockaddr* host_and_af2sockaddr(const char *host, int port, sa_family_t af);
    351 len_and_sockaddr* xhost_and_af2sockaddr(const char *host, int port, sa_family_t af);
    352 #else
    353 /* [we evaluate af: think about "host_and_af2sockaddr(..., af++)"] */
    354 #define host_and_af2sockaddr(host, port, af) ((void)(af), host2sockaddr((host), (port)))
    355 #define xhost_and_af2sockaddr(host, port, af) ((void)(af), xhost2sockaddr((host), (port)))
     555#if !ENABLE_FEATURE_IPV6
     556#define host_and_af2sockaddr(host, port, af) host2sockaddr((host), (port))
     557#define xhost_and_af2sockaddr(host, port, af) xhost2sockaddr((host), (port))
     558#else
     559len_and_sockaddr* host_and_af2sockaddr(const char *host, int port, sa_family_t af) FAST_FUNC RETURNS_MALLOC;
     560len_and_sockaddr* xhost_and_af2sockaddr(const char *host, int port, sa_family_t af) FAST_FUNC RETURNS_MALLOC;
    356561#endif
    357562/* Assign sin[6]_port member if the socket is an AF_INET[6] one,
    358563 * otherwise no-op. Useful for ftp.
    359564 * NB: does NOT do htons() internally, just direct assignment. */
    360 void set_nport(len_and_sockaddr *lsa, unsigned port);
     565void set_nport(len_and_sockaddr *lsa, unsigned port) FAST_FUNC;
    361566/* Retrieve sin[6]_port or return -1 for non-INET[6] lsa's */
    362 int get_nport(const struct sockaddr *sa);
     567int get_nport(const struct sockaddr *sa) FAST_FUNC;
    363568/* Reverse DNS. Returns NULL on failure. */
    364 char* xmalloc_sockaddr2host(const struct sockaddr *sa);
     569char* xmalloc_sockaddr2host(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
    365570/* This one doesn't append :PORTNUM */
    366 char* xmalloc_sockaddr2host_noport(const struct sockaddr *sa);
     571char* xmalloc_sockaddr2host_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
    367572/* This one also doesn't fall back to dotted IP (returns NULL) */
    368 char* xmalloc_sockaddr2hostonly_noport(const struct sockaddr *sa);
     573char* xmalloc_sockaddr2hostonly_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
    369574/* inet_[ap]ton on steroids */
    370 char* xmalloc_sockaddr2dotted(const struct sockaddr *sa);
    371 char* xmalloc_sockaddr2dotted_noport(const struct sockaddr *sa);
     575char* xmalloc_sockaddr2dotted(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
     576char* xmalloc_sockaddr2dotted_noport(const struct sockaddr *sa) FAST_FUNC RETURNS_MALLOC;
    372577// "old" (ipv4 only) API
    373578// users: traceroute.c hostname.c - use _list_ of all IPs
    374 struct hostent *xgethostbyname(const char *name);
     579struct hostent *xgethostbyname(const char *name) FAST_FUNC;
    375580// Also mount.c and inetd.c are using gethostbyname(),
    376581// + inet_common.c has additional IPv4-only stuff
    377582
    378583
    379 void socket_want_pktinfo(int fd);
     584void socket_want_pktinfo(int fd) FAST_FUNC;
    380585ssize_t send_to_from(int fd, void *buf, size_t len, int flags,
    381         const struct sockaddr *from, const struct sockaddr *to,
    382         socklen_t tolen);
     586        const struct sockaddr *to,
     587        const struct sockaddr *from,
     588        socklen_t tolen) FAST_FUNC;
    383589ssize_t recv_from_to(int fd, void *buf, size_t len, int flags,
    384         struct sockaddr *from, struct sockaddr *to,
    385         socklen_t sa_size);
    386 
    387 
    388 extern char *xstrdup(const char *s);
    389 extern char *xstrndup(const char *s, int n);
    390 extern char *safe_strncpy(char *dst, const char *src, size_t size);
    391 extern char *xasprintf(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
     590        struct sockaddr *from,
     591        struct sockaddr *to,
     592        socklen_t sa_size) FAST_FUNC;
     593
     594
     595char *xstrdup(const char *s) FAST_FUNC RETURNS_MALLOC;
     596char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC;
     597void overlapping_strcpy(char *dst, const char *src) FAST_FUNC;
     598char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC;
     599char *strncpy_IFNAMSIZ(char *dst, const char *src) FAST_FUNC;
     600/* Guaranteed to NOT be a macro (smallest code). Saves nearly 2k on uclibc.
     601 * But potentially slow, don't use in one-billion-times loops */
     602int bb_putchar(int ch) FAST_FUNC;
     603/* Note: does not use stdio, writes to fd 2 directly */
     604int bb_putchar_stderr(char ch) FAST_FUNC;
     605char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC;
    392606// gcc-4.1.1 still isn't good enough at optimizing it
    393607// (+200 bytes compared to macro)
     
    402616#define DOT_OR_DOTDOT(s) ((s)[0] == '.' && (!(s)[1] || ((s)[1] == '.' && !(s)[2])))
    403617
     618typedef struct uni_stat_t {
     619    unsigned byte_count;
     620    unsigned unicode_count;
     621    unsigned unicode_width;
     622} uni_stat_t;
     623/* Returns a string with unprintable chars replaced by '?' or
     624 * SUBST_WCHAR. This function is unicode-aware. */
     625const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str);
     626/* Prints unprintable char ch as ^C or M-c to file
     627 * (M-c is used only if ch is ORed with PRINTABLE_META),
     628 * else it is printed as-is (except for ch = 0x9b) */
     629enum { PRINTABLE_META = 0x100 };
     630void fputc_printable(int ch, FILE *file) FAST_FUNC;
     631
    404632/* dmalloc will redefine these to it's own implementation. It is safe
    405633 * to have the prototypes here unconditionally.  */
    406 extern void *malloc_or_warn(size_t size);
    407 extern void *xmalloc(size_t size);
    408 extern void *xzalloc(size_t size);
    409 extern void *xrealloc(void *old, size_t size);
    410 
    411 extern ssize_t safe_read(int fd, void *buf, size_t count);
    412 extern ssize_t full_read(int fd, void *buf, size_t count);
    413 extern void xread(int fd, void *buf, size_t count);
    414 extern unsigned char xread_char(int fd);
    415 // Read one line a-la fgets. Uses one read(), works only on seekable streams
    416 extern char *reads(int fd, char *buf, size_t count);
    417 // Read one line a-la fgets. Reads byte-by-byte.
    418 // Useful when it is important to not read ahead.
    419 extern char *xmalloc_reads(int fd, char *pfx);
    420 extern ssize_t read_close(int fd, void *buf, size_t count);
    421 extern ssize_t open_read_close(const char *filename, void *buf, size_t count);
    422 extern void *xmalloc_open_read_close(const char *filename, size_t *sizep);
    423 
    424 extern ssize_t safe_write(int fd, const void *buf, size_t count);
    425 extern ssize_t full_write(int fd, const void *buf, size_t count);
    426 extern void xwrite(int fd, const void *buf, size_t count);
     634void *malloc_or_warn(size_t size) FAST_FUNC RETURNS_MALLOC;
     635void *xmalloc(size_t size) FAST_FUNC RETURNS_MALLOC;
     636void *xzalloc(size_t size) FAST_FUNC RETURNS_MALLOC;
     637void *xrealloc(void *old, size_t size) FAST_FUNC;
     638/* After xrealloc_vector(v, 4, idx) it's ok to use
     639 * at least v[idx] and v[idx+1], for all idx values.
     640 * shift specifies how many new elements are added (1: 2, 2: 4... 8: 256...)
     641 * when all elements are used up. New elements are zeroed out. */
     642#define xrealloc_vector(vector, shift, idx) \
     643    xrealloc_vector_helper((vector), (sizeof((vector)[0]) << 8) + (shift), (idx))
     644void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) FAST_FUNC;
     645
     646
     647extern ssize_t safe_read(int fd, void *buf, size_t count) FAST_FUNC;
     648extern ssize_t nonblock_safe_read(int fd, void *buf, size_t count) FAST_FUNC;
     649// NB: will return short read on error, not -1,
     650// if some data was read before error occurred
     651extern ssize_t full_read(int fd, void *buf, size_t count) FAST_FUNC;
     652extern void xread(int fd, void *buf, size_t count) FAST_FUNC;
     653extern unsigned char xread_char(int fd) FAST_FUNC;
     654extern ssize_t read_close(int fd, void *buf, size_t maxsz) FAST_FUNC;
     655extern ssize_t open_read_close(const char *filename, void *buf, size_t maxsz) FAST_FUNC;
     656// Reads one line a-la fgets (but doesn't save terminating '\n').
     657// Reads byte-by-byte. Useful when it is important to not read ahead.
     658// Bytes are appended to pfx (which must be malloced, or NULL).
     659extern char *xmalloc_reads(int fd, char *pfx, size_t *maxsz_p) FAST_FUNC;
     660/* Reads block up to *maxsz_p (default: INT_MAX - 4095) */
     661extern void *xmalloc_read(int fd, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
     662/* Returns NULL if file can't be opened (default max size: INT_MAX - 4095) */
     663extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
     664/* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */
     665#if ENABLE_FEATURE_SEAMLESS_LZMA \
     666 || ENABLE_FEATURE_SEAMLESS_BZ2 \
     667 || ENABLE_FEATURE_SEAMLESS_GZ \
     668 /* || ENABLE_FEATURE_SEAMLESS_Z */
     669extern void setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) FAST_FUNC;
     670#else
     671# define setup_unzip_on_fd(...) ((void)0)
     672#endif
     673/* Autodetects .gz etc */
     674extern int open_zipped(const char *fname) FAST_FUNC;
     675extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
     676/* Never returns NULL */
     677extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
     678
     679extern ssize_t safe_write(int fd, const void *buf, size_t count) FAST_FUNC;
     680// NB: will return short write on error, not -1,
     681// if some data was written before error occurred
     682extern ssize_t full_write(int fd, const void *buf, size_t count) FAST_FUNC;
     683extern void xwrite(int fd, const void *buf, size_t count) FAST_FUNC;
     684extern void xwrite_str(int fd, const char *str) FAST_FUNC;
     685extern ssize_t full_write1_str(const char *str) FAST_FUNC;
     686extern ssize_t full_write2_str(const char *str) FAST_FUNC;
     687extern void xopen_xwrite_close(const char* file, const char *str) FAST_FUNC;
     688
     689/* Close fd, but check for failures (some types of write errors) */
     690extern void xclose(int fd) FAST_FUNC;
    427691
    428692/* Reads and prints to stdout till eof, then closes FILE. Exits on error: */
    429 extern void xprint_and_close_file(FILE *file);
    430 extern char *xmalloc_fgets(FILE *file);
    431 /* Read up to (and including) TERMINATING_STRING: */
    432 extern char *xmalloc_fgets_str(FILE *file, const char *terminating_string);
     693extern void xprint_and_close_file(FILE *file) FAST_FUNC;
     694
     695extern char *bb_get_chunk_from_file(FILE *file, int *end) FAST_FUNC;
     696extern char *bb_get_chunk_with_continuation(FILE *file, int *end, int *lineno) FAST_FUNC;
     697/* Reads up to (and including) TERMINATING_STRING: */
     698extern char *xmalloc_fgets_str(FILE *file, const char *terminating_string) FAST_FUNC RETURNS_MALLOC;
     699/* Same, with limited max size, and returns the length (excluding NUL): */
     700extern char *xmalloc_fgets_str_len(FILE *file, const char *terminating_string, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
     701/* Chops off TERMINATING_STRING from the end: */
     702extern char *xmalloc_fgetline_str(FILE *file, const char *terminating_string) FAST_FUNC RETURNS_MALLOC;
     703/* Reads up to (and including) "\n" or NUL byte: */
     704extern char *xmalloc_fgets(FILE *file) FAST_FUNC RETURNS_MALLOC;
    433705/* Chops off '\n' from the end, unlike fgets: */
    434 extern char *xmalloc_getline(FILE *file);
    435 extern char *bb_get_chunk_from_file(FILE *file, int *end);
    436 extern void die_if_ferror(FILE *file, const char *msg);
    437 extern void die_if_ferror_stdout(void);
    438 extern void xfflush_stdout(void);
    439 extern void fflush_stdout_and_exit(int retval) ATTRIBUTE_NORETURN;
    440 extern int fclose_if_not_stdin(FILE *file);
    441 extern FILE *xfopen(const char *filename, const char *mode);
     706extern char *xmalloc_fgetline(FILE *file) FAST_FUNC RETURNS_MALLOC;
     707/* Same, but doesn't try to conserve space (may have some slack after the end) */
     708/* extern char *xmalloc_fgetline_fast(FILE *file) FAST_FUNC RETURNS_MALLOC; */
     709
     710void die_if_ferror(FILE *file, const char *msg) FAST_FUNC;
     711void die_if_ferror_stdout(void) FAST_FUNC;
     712int fflush_all(void) FAST_FUNC;
     713void fflush_stdout_and_exit(int retval) NORETURN FAST_FUNC;
     714int fclose_if_not_stdin(FILE *file) FAST_FUNC;
     715FILE* xfopen(const char *filename, const char *mode) FAST_FUNC;
    442716/* Prints warning to stderr and returns NULL on failure: */
    443 extern FILE *fopen_or_warn(const char *filename, const char *mode);
     717FILE* fopen_or_warn(const char *filename, const char *mode) FAST_FUNC;
    444718/* "Opens" stdin if filename is special, else just opens file: */
    445 extern FILE *fopen_or_warn_stdin(const char *filename);
     719FILE* xfopen_stdin(const char *filename) FAST_FUNC;
     720FILE* fopen_or_warn_stdin(const char *filename) FAST_FUNC;
     721FILE* fopen_for_read(const char *path) FAST_FUNC;
     722FILE* xfopen_for_read(const char *path) FAST_FUNC;
     723FILE* fopen_for_write(const char *path) FAST_FUNC;
     724FILE* xfopen_for_write(const char *path) FAST_FUNC;
     725FILE* xfdopen_for_read(int fd) FAST_FUNC;
     726FILE* xfdopen_for_write(int fd) FAST_FUNC;
     727
     728int bb_pstrcmp(const void *a, const void *b) /* not FAST_FUNC! */;
     729void qsort_string_vector(char **sv, unsigned count) FAST_FUNC;
     730
     731/* Wrapper which restarts poll on EINTR or ENOMEM.
     732 * On other errors complains [perror("poll")] and returns.
     733 * Warning! May take (much) longer than timeout_ms to return!
     734 * If this is a problem, use bare poll and open-code EINTR/ENOMEM handling */
     735int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout_ms) FAST_FUNC;
     736
     737char *safe_gethostname(void) FAST_FUNC;
     738char *safe_getdomainname(void) FAST_FUNC;
    446739
    447740/* Convert each alpha char in str to lower-case */
    448 extern char* str_tolower(char *str);
    449 
    450 char *utoa(unsigned n);
    451 char *itoa(int n);
     741char* str_tolower(char *str) FAST_FUNC;
     742
     743char *utoa(unsigned n) FAST_FUNC;
     744char *itoa(int n) FAST_FUNC;
    452745/* Returns a pointer past the formatted number, does NOT null-terminate */
    453 char *utoa_to_buf(unsigned n, char *buf, unsigned buflen);
    454 char *itoa_to_buf(int n, char *buf, unsigned buflen);
    455 void smart_ulltoa5(unsigned long long ul, char buf[5]);
     746char *utoa_to_buf(unsigned n, char *buf, unsigned buflen) FAST_FUNC;
     747char *itoa_to_buf(int n, char *buf, unsigned buflen) FAST_FUNC;
     748/* Intelligent formatters of bignums */
     749void smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale) FAST_FUNC;
     750void smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC;
     751/* If block_size == 0, display size without fractional part,
     752 * else display (size * block_size) with one decimal digit.
     753 * If display_unit == 0, show value no bigger than 1024 with suffix (K,M,G...),
     754 * else divide by display_unit and do not use suffix. */
     755#define HUMAN_READABLE_MAX_WIDTH      7  /* "1024.0G" */
     756#define HUMAN_READABLE_MAX_WIDTH_STR "7"
    456757//TODO: provide pointer to buf (avoid statics)?
    457758const char *make_human_readable_str(unsigned long long size,
    458         unsigned long block_size, unsigned long display_unit);
     759        unsigned long block_size, unsigned long display_unit) FAST_FUNC;
    459760/* Put a string of hex bytes ("1b2e66fe"...), return advanced pointer */
    460 char *bin2hex(char *buf, const char *cp, int count);
     761char *bin2hex(char *buf, const char *cp, int count) FAST_FUNC;
     762/* Reverse */
     763char* hex2bin(char *dst, const char *str, int count) FAST_FUNC;
     764
     765/* Generate a UUID */
     766void generate_uuid(uint8_t *buf) FAST_FUNC;
    461767
    462768/* Last element is marked by mult == 0 */
     
    467773#include "xatonum.h"
    468774/* Specialized: */
     775
    469776/* Using xatoi() instead of naive atoi() is not always convenient -
    470777 * in many places people want *non-negative* values, but store them
    471778 * in signed int. Therefore we need this one:
    472  * dies if input is not in [0, INT_MAX] range. Also will reject '-0' etc */
    473 int xatoi_u(const char *numstr);
     779 * dies if input is not in [0, INT_MAX] range. Also will reject '-0' etc.
     780 * It should really be named xatoi_nonnegative (since it allows 0),
     781 * but that would be too long.
     782 */
     783int xatoi_positive(const char *numstr) FAST_FUNC;
     784
    474785/* Useful for reading port numbers */
    475 uint16_t xatou16(const char *numstr);
     786uint16_t xatou16(const char *numstr) FAST_FUNC;
    476787
    477788
     
    479790 * for BusyBox since we want to avoid using the glibc NSS stuff, which
    480791 * increases target size and is often not needed on embedded systems.  */
    481 long xuname2uid(const char *name);
    482 long xgroup2gid(const char *name);
     792long xuname2uid(const char *name) FAST_FUNC;
     793long xgroup2gid(const char *name) FAST_FUNC;
    483794/* wrapper: allows string to contain numeric uid or gid */
    484 unsigned long get_ug_id(const char *s, long (*xname2id)(const char *));
     795unsigned long get_ug_id(const char *s, long FAST_FUNC (*xname2id)(const char *)) FAST_FUNC;
    485796/* from chpst. Does not die, returns 0 on failure */
    486797struct bb_uidgid_t {
     
    489800};
    490801/* always sets uid and gid */
    491 int get_uidgid(struct bb_uidgid_t*, const char*, int numeric_ok);
     802int get_uidgid(struct bb_uidgid_t*, const char*, int numeric_ok) FAST_FUNC;
     803/* always sets uid and gid, allows numeric; exits on failure */
     804void xget_uidgid(struct bb_uidgid_t*, const char*) FAST_FUNC;
    492805/* chown-like handling of "user[:[group]" */
    493 void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group);
    494 /* bb_getpwuid, bb_getgrgid:
    495  * bb_getXXXid(buf, bufsz, id) - copy user/group name or id
    496  *              as a string to buf, return user/group name or NULL
    497  * bb_getXXXid(NULL, 0, id) - return user/group name or NULL
    498  * bb_getXXXid(NULL, -1, id) - return user/group name or exit
    499 */
    500 char *bb_getpwuid(char *name, int bufsize, long uid);
    501 char *bb_getgrgid(char *group, int bufsize, long gid);
     806void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group) FAST_FUNC;
     807struct passwd* xgetpwnam(const char *name) FAST_FUNC;
     808struct group* xgetgrnam(const char *name) FAST_FUNC;
     809struct passwd* xgetpwuid(uid_t uid) FAST_FUNC;
     810struct group* xgetgrgid(gid_t gid) FAST_FUNC;
     811char* xuid2uname(uid_t uid) FAST_FUNC;
     812char* xgid2group(gid_t gid) FAST_FUNC;
     813char* uid2uname(uid_t uid) FAST_FUNC;
     814char* gid2group(gid_t gid) FAST_FUNC;
     815char* uid2uname_utoa(long uid) FAST_FUNC;
     816char* gid2group_utoa(long gid) FAST_FUNC;
    502817/* versions which cache results (useful for ps, ls etc) */
    503 const char* get_cached_username(uid_t uid);
    504 const char* get_cached_groupname(gid_t gid);
    505 void clear_username_cache(void);
     818const char* get_cached_username(uid_t uid) FAST_FUNC;
     819const char* get_cached_groupname(gid_t gid) FAST_FUNC;
     820void clear_username_cache(void) FAST_FUNC;
    506821/* internally usernames are saved in fixed-sized char[] buffers */
    507822enum { USERNAME_MAX_SIZE = 16 - sizeof(int) };
    508 
    509 
    510 struct bb_applet;
    511 int execable_file(const char *name);
    512 char *find_execable(const char *filename);
    513 int exists_execable(const char *filename);
    514 
     823#if ENABLE_FEATURE_CHECK_NAMES
     824void die_if_bad_username(const char* name) FAST_FUNC;
     825#else
     826#define die_if_bad_username(name) ((void)(name))
     827#endif
     828
     829#if ENABLE_FEATURE_UTMP
     830void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
     831void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
     832#else
     833# define write_new_utmp(pid, new_type, tty_name, username, hostname) ((void)0)
     834# define update_utmp(pid, new_type, tty_name, username, hostname) ((void)0)
     835#endif
     836
     837int execable_file(const char *name) FAST_FUNC;
     838char *find_execable(const char *filename, char **PATHp) FAST_FUNC;
     839int exists_execable(const char *filename) FAST_FUNC;
     840
     841/* BB_EXECxx always execs (it's not doing NOFORK/NOEXEC stuff),
     842 * but it may exec busybox and call applet instead of searching PATH.
     843 */
    515844#if ENABLE_FEATURE_PREFER_APPLETS
    516 int bb_execvp(const char *file, char *const argv[]);
     845int bb_execvp(const char *file, char *const argv[]) FAST_FUNC;
    517846#define BB_EXECVP(prog,cmd) bb_execvp(prog,cmd)
    518847#define BB_EXECLP(prog,cmd,...) \
    519     execlp((find_applet_by_name(prog)) ? CONFIG_BUSYBOX_EXEC_PATH : prog, \
     848    execlp((find_applet_by_name(prog) >= 0) ? CONFIG_BUSYBOX_EXEC_PATH : prog, \
    520849        cmd, __VA_ARGS__)
    521850#else
     
    523852#define BB_EXECLP(prog,cmd,...) execlp(prog,cmd, __VA_ARGS__)
    524853#endif
    525 
    526 /* NOMMU friendy fork+exec */
    527 pid_t spawn(char **argv);
    528 pid_t xspawn(char **argv);
    529 
    530 /* Unlike waitpid, waits ONLY for one process,
     854int BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;
     855
     856/* xvfork() can't be a _function_, return after vfork mangles stack
     857 * in the parent. It must be a macro. */
     858#define xvfork() \
     859({ \
     860    pid_t bb__xvfork_pid = vfork(); \
     861    if (bb__xvfork_pid < 0) \
     862        bb_perror_msg_and_die("vfork"); \
     863    bb__xvfork_pid; \
     864})
     865#if BB_MMU
     866pid_t xfork(void) FAST_FUNC;
     867#endif
     868
     869/* NOMMU friendy fork+exec: */
     870pid_t spawn(char **argv) FAST_FUNC;
     871pid_t xspawn(char **argv) FAST_FUNC;
     872
     873pid_t safe_waitpid(pid_t pid, int *wstat, int options) FAST_FUNC;
     874pid_t wait_any_nohang(int *wstat) FAST_FUNC;
     875/* wait4pid: unlike waitpid, waits ONLY for one process.
     876 * Returns sig + 0x180 if child is killed by signal.
    531877 * It's safe to pass negative 'pids' from failed [v]fork -
    532878 * wait4pid will return -1 (and will not clobber [v]fork's errno).
    533879 * IOW: rc = wait4pid(spawn(argv));
    534880 *      if (rc < 0) bb_perror_msg("%s", argv[0]);
    535  *      if (rc > 0) bb_error_msg("exit code: %d", rc);
     881 *      if (rc > 0) bb_error_msg("exit code: %d", rc & 0xff);
    536882 */
    537 int wait4pid(int pid);
    538 int wait_pid(int *wstat, int pid);
    539 int wait_nohang(int *wstat);
    540 #define wait_crashed(w) ((w) & 127)
    541 #define wait_exitcode(w) ((w) >> 8)
    542 #define wait_stopsig(w) ((w) >> 8)
    543 #define wait_stopped(w) (((w) & 127) == 127)
    544 /* wait4pid(spawn(argv)) + NOFORK/NOEXEC (if configured) */
    545 int spawn_and_wait(char **argv);
     883int wait4pid(pid_t pid) FAST_FUNC;
     884/* Same as wait4pid(spawn(argv)), but with NOFORK/NOEXEC if configured: */
     885int spawn_and_wait(char **argv) FAST_FUNC;
    546886struct nofork_save_area {
    547887    jmp_buf die_jmp;
    548     const struct bb_applet *current_applet;
    549     int xfunc_error_retval;
     888    const char *applet_name;
    550889    uint32_t option_mask32;
    551890    int die_sleep;
     891    uint8_t xfunc_error_retval;
    552892    smallint saved;
    553893};
    554 void save_nofork_data(struct nofork_save_area *save);
    555 void restore_nofork_data(struct nofork_save_area *save);
     894void save_nofork_data(struct nofork_save_area *save) FAST_FUNC;
     895void restore_nofork_data(struct nofork_save_area *save) FAST_FUNC;
    556896/* Does NOT check that applet is NOFORK, just blindly runs it */
    557 int run_nofork_applet(const struct bb_applet *a, char **argv);
    558 int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet *a, char **argv);
     897int run_nofork_applet(int applet_no, char **argv) FAST_FUNC;
     898int run_nofork_applet_prime(struct nofork_save_area *old, int applet_no, char **argv) FAST_FUNC;
    559899
    560900/* Helpers for daemonization.
     
    572912 * (will do setsid()).
    573913 *
    574  * forkexit_or_rexec(argv) = bare-bones "fork + parent exits" on MMU,
     914 * fork_or_rexec(argv) = bare-bones fork on MMU,
    575915 *      "vfork + re-exec ourself" on NOMMU. No fd redirection, no setsid().
    576  *      Currently used for openvt. On MMU ignores argv.
     916 *      On MMU ignores argv.
    577917 *
    578918 * Helper for network daemons in foreground mode:
     
    588928};
    589929#if BB_MMU
    590   void forkexit_or_rexec(void);
    591930  enum { re_execed = 0 };
    592 # define forkexit_or_rexec(argv)            forkexit_or_rexec()
     931# define fork_or_rexec(argv)                xfork()
    593932# define bb_daemonize_or_rexec(flags, argv) bb_daemonize_or_rexec(flags)
    594933# define bb_daemonize(flags)                bb_daemonize_or_rexec(flags, bogus)
    595934#else
    596   void re_exec(char **argv) ATTRIBUTE_NORETURN;
    597   void forkexit_or_rexec(char **argv);
    598935  extern bool re_execed;
     936  void re_exec(char **argv) NORETURN FAST_FUNC;
     937  pid_t fork_or_rexec(char **argv) FAST_FUNC;
     938  int  BUG_fork_is_unavailable_on_nommu(void) FAST_FUNC;
     939  int  BUG_daemon_is_unavailable_on_nommu(void) FAST_FUNC;
     940  void BUG_bb_daemonize_is_unavailable_on_nommu(void) FAST_FUNC;
    599941# define fork()          BUG_fork_is_unavailable_on_nommu()
     942# define xfork()         BUG_fork_is_unavailable_on_nommu()
    600943# define daemon(a,b)     BUG_daemon_is_unavailable_on_nommu()
    601944# define bb_daemonize(a) BUG_bb_daemonize_is_unavailable_on_nommu()
    602945#endif
    603 void bb_daemonize_or_rexec(int flags, char **argv);
    604 void bb_sanitize_stdio(void);
    605 
    606 
     946void bb_daemonize_or_rexec(int flags, char **argv) FAST_FUNC;
     947void bb_sanitize_stdio(void) FAST_FUNC;
     948/* Clear dangerous stuff, set PATH. Return 1 if was run by different user. */
     949int sanitize_env_if_suid(void) FAST_FUNC;
     950
     951
     952char* single_argv(char **argv) FAST_FUNC;
     953extern const char *const bb_argv_dash[]; /* "-", NULL */
    607954extern const char *opt_complementary;
    608 #if ENABLE_GETOPT_LONG
     955#if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG
    609956#define No_argument "\0"
    610957#define Required_argument "\001"
     
    613960#endif
    614961extern uint32_t option_mask32;
    615 extern uint32_t getopt32(char **argv, const char *applet_opts, ...);
     962extern uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC;
    616963
    617964
     
    620967    struct llist_t *link;
    621968} llist_t;
    622 void llist_add_to(llist_t **old_head, void *data);
    623 void llist_add_to_end(llist_t **list_head, void *data);
    624 void *llist_pop(llist_t **elm);
    625 void llist_unlink(llist_t **head, llist_t *elm);
    626 void llist_free(llist_t *elm, void (*freeit)(void *data));
    627 llist_t *llist_rev(llist_t *list);
     969void llist_add_to(llist_t **old_head, void *data) FAST_FUNC;
     970void llist_add_to_end(llist_t **list_head, void *data) FAST_FUNC;
     971void *llist_pop(llist_t **elm) FAST_FUNC;
     972void llist_unlink(llist_t **head, llist_t *elm) FAST_FUNC;
     973void llist_free(llist_t *elm, void (*freeit)(void *data)) FAST_FUNC;
     974llist_t *llist_rev(llist_t *list) FAST_FUNC;
     975llist_t *llist_find_str(llist_t *first, const char *str) FAST_FUNC;
    628976/* BTW, surprisingly, changing API to
    629977 *   llist_t *llist_add_to(llist_t *old_head, void *data)
     
    635983/* True only if we created pidfile which is *file*, not /dev/null etc */
    636984extern smallint wrote_pidfile;
    637 void write_pidfile(const char *path);
     985void write_pidfile(const char *path) FAST_FUNC;
    638986#define remove_pidfile(path) do { if (wrote_pidfile) unlink(path); } while (0)
    639987#else
     
    6521000extern smallint logmode;
    6531001extern int die_sleep;
    654 extern int xfunc_error_retval;
     1002extern uint8_t xfunc_error_retval;
    6551003extern jmp_buf die_jmp;
    656 extern void xfunc_die(void) ATTRIBUTE_NORETURN;
    657 extern void bb_show_usage(void) ATTRIBUTE_NORETURN ATTRIBUTE_EXTERNALLY_VISIBLE;
    658 extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
    659 extern void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
    660 extern void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
    661 extern void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
    662 extern void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
    663 extern void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
    664 extern void bb_perror_nomsg_and_die(void) ATTRIBUTE_NORETURN;
    665 extern void bb_perror_nomsg(void);
    666 extern void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
    667 extern void bb_verror_msg(const char *s, va_list p, const char *strerr);
    668 
    669 
    670 /* applets which are useful from another applets */
     1004extern void xfunc_die(void) NORETURN FAST_FUNC;
     1005extern void bb_show_usage(void) NORETURN FAST_FUNC;
     1006extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
     1007extern void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
     1008extern void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
     1009extern void bb_simple_perror_msg(const char *s) FAST_FUNC;
     1010extern void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
     1011extern void bb_simple_perror_msg_and_die(const char *s) NORETURN FAST_FUNC;
     1012extern void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
     1013extern void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
     1014extern void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC;
     1015extern void bb_perror_nomsg(void) FAST_FUNC;
     1016extern void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
     1017extern void bb_verror_msg(const char *s, va_list p, const char *strerr) FAST_FUNC;
     1018
     1019/* We need to export XXX_main from libbusybox
     1020 * only if we build "individual" binaries
     1021 */
     1022#if ENABLE_FEATURE_INDIVIDUAL
     1023#define MAIN_EXTERNALLY_VISIBLE EXTERNALLY_VISIBLE
     1024#else
     1025#define MAIN_EXTERNALLY_VISIBLE
     1026#endif
     1027
     1028
     1029/* Applets which are useful from another applets */
    6711030int bb_cat(char** argv);
    672 int bb_echo(char** argv);
    673 int test_main(int argc, char** argv);
    674 int kill_main(int argc, char **argv);
     1031/* If shell needs them, they exist even if not enabled as applets */
     1032int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE);
     1033int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE);
     1034int test_main(int argc, char **argv) IF_TEST(MAIN_EXTERNALLY_VISIBLE);
     1035int kill_main(int argc, char **argv) IF_KILL(MAIN_EXTERNALLY_VISIBLE);
     1036/* Similar, but used by chgrp, not shell */
     1037int chown_main(int argc, char **argv) IF_CHOWN(MAIN_EXTERNALLY_VISIBLE);
     1038/* Used by ftpd */
     1039int ls_main(int argc, char **argv) IF_LS(MAIN_EXTERNALLY_VISIBLE);
     1040/* Don't need IF_xxx() guard for these */
     1041int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     1042int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     1043
    6751044#if ENABLE_ROUTE
    676 void bb_displayroutes(int noresolve, int netstatfmt);
    677 #endif
    678 int chown_main(int argc, char **argv);
    679 #if ENABLE_GUNZIP
    680 int gunzip_main(int argc, char **argv);
    681 #endif
    682 int bbunpack(char **argv,
    683     char* (*make_new_name)(char *filename),
    684     USE_DESKTOP(long long) int (*unpacker)(void)
    685 );
     1045void bb_displayroutes(int noresolve, int netstatfmt) FAST_FUNC;
     1046#endif
    6861047
    6871048
    6881049/* Networking */
    689 int create_icmp_socket(void);
    690 int create_icmp6_socket(void);
     1050int create_icmp_socket(void) FAST_FUNC;
     1051int create_icmp6_socket(void) FAST_FUNC;
    6911052/* interface.c */
    6921053/* This structure defines protocol families and their handlers. */
     
    6961057    int af;
    6971058    int alen;
    698     char *(*print) (unsigned char *);
    699     const char *(*sprint) (struct sockaddr *, int numeric);
    700     int (*input) (/*int type,*/ const char *bufp, struct sockaddr *);
    701     void (*herror) (char *text);
    702     int (*rprint) (int options);
    703     int (*rinput) (int typ, int ext, char **argv);
    704 
     1059    char*       FAST_FUNC (*print)(unsigned char *);
     1060    const char* FAST_FUNC (*sprint)(struct sockaddr *, int numeric);
     1061    int         FAST_FUNC (*input)(/*int type,*/ const char *bufp, struct sockaddr *);
     1062    void        FAST_FUNC (*herror)(char *text);
     1063    int         FAST_FUNC (*rprint)(int options);
     1064    int         FAST_FUNC (*rinput)(int typ, int ext, char **argv);
    7051065    /* may modify src */
    706     int (*getmask) (char *src, struct sockaddr * mask, char *name);
     1066    int         FAST_FUNC (*getmask)(char *src, struct sockaddr *mask, char *name);
    7071067};
    7081068/* This structure defines hardware protocols and their handlers. */
     
    7121072    int type;
    7131073    int alen;
    714     char *(*print) (unsigned char *);
    715     int (*input) (const char *, struct sockaddr *);
    716     int (*activate) (int fd);
     1074    char* FAST_FUNC (*print)(unsigned char *);
     1075    int   FAST_FUNC (*input)(const char *, struct sockaddr *);
     1076    int   FAST_FUNC (*activate)(int fd);
    7171077    int suppress_null_addr;
    7181078};
    7191079extern smallint interface_opt_a;
    720 int display_interfaces(char *ifname);
    721 const struct aftype *get_aftype(const char *name);
    722 const struct hwtype *get_hwtype(const char *name);
    723 const struct hwtype *get_hwntype(int type);
     1080int display_interfaces(char *ifname) FAST_FUNC;
     1081#if ENABLE_FEATURE_HWIB
     1082int in_ib(const char *bufp, struct sockaddr *sap) FAST_FUNC;
     1083#else
     1084#define in_ib(a, b) 1 /* fail */
     1085#endif
     1086const struct aftype *get_aftype(const char *name) FAST_FUNC;
     1087const struct hwtype *get_hwtype(const char *name) FAST_FUNC;
     1088const struct hwtype *get_hwntype(int type) FAST_FUNC;
    7241089
    7251090
    7261091#ifndef BUILD_INDIVIDUAL
    727 extern const struct bb_applet *find_applet_by_name(const char *name);
     1092extern int find_applet_by_name(const char *name) FAST_FUNC;
    7281093/* Returns only if applet is not found. */
    729 extern void run_applet_and_exit(const char *name, char **argv);
    730 extern void run_current_applet_and_exit(char **argv) ATTRIBUTE_NORETURN;
    731 #endif
    732 
    733 extern int match_fstype(const struct mntent *mt, const char *fstypes);
    734 extern struct mntent *find_mount_point(const char *name, const char *table);
    735 extern void erase_mtab(const char * name);
    736 extern unsigned int tty_baud_to_value(speed_t speed);
    737 extern speed_t tty_value_to_baud(unsigned int value);
    738 extern void bb_warn_ignoring_args(int n);
    739 
    740 extern int get_linux_version_code(void);
    741 
    742 extern char *query_loop(const char *device);
    743 extern int del_loop(const char *device);
     1094extern void run_applet_and_exit(const char *name, char **argv) FAST_FUNC;
     1095extern void run_applet_no_and_exit(int a, char **argv) NORETURN FAST_FUNC;
     1096#endif
     1097
     1098#ifdef HAVE_MNTENT_H
     1099extern int match_fstype(const struct mntent *mt, const char *fstypes) FAST_FUNC;
     1100extern struct mntent *find_mount_point(const char *name, int subdir_too) FAST_FUNC;
     1101#endif
     1102extern void erase_mtab(const char * name) FAST_FUNC;
     1103extern unsigned int tty_baud_to_value(speed_t speed) FAST_FUNC;
     1104extern speed_t tty_value_to_baud(unsigned int value) FAST_FUNC;
     1105#if ENABLE_DESKTOP
     1106extern void bb_warn_ignoring_args(char *arg) FAST_FUNC;
     1107#else
     1108# define bb_warn_ignoring_args(arg) ((void)0)
     1109#endif
     1110
     1111extern int get_linux_version_code(void) FAST_FUNC;
     1112
     1113extern char *query_loop(const char *device) FAST_FUNC;
     1114extern int del_loop(const char *device) FAST_FUNC;
    7441115/* If *devname is not NULL, use that name, otherwise try to find free one,
    7451116 * malloc and return it in *devname.
    7461117 * return value: 1: read-only loopdev was setup, 0: rw, < 0: error */
    747 extern int set_loop(char **devname, const char *file, unsigned long long offset);
    748 
    749 
     1118extern int set_loop(char **devname, const char *file, unsigned long long offset) FAST_FUNC;
     1119
     1120/* Like bb_ask below, but asks on stdin with no timeout.  */
     1121char *bb_ask_stdin(const char * prompt) FAST_FUNC;
    7501122//TODO: pass buf pointer or return allocated buf (avoid statics)?
    751 char *bb_askpass(int timeout, const char * prompt);
    752 int bb_ask_confirmation(void);
    753 int klogctl(int type, char * b, int len);
    754 
    755 extern int bb_parse_mode(const char* s, mode_t* theMode);
    756 
    757 char *concat_path_file(const char *path, const char *filename);
    758 char *concat_subpath_file(const char *path, const char *filename);
    759 const char *bb_basename(const char *name);
     1123char *bb_ask(const int fd, int timeout, const char * prompt) FAST_FUNC;
     1124int bb_ask_confirmation(void) FAST_FUNC;
     1125
     1126int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC;
     1127
     1128/*
     1129 * Config file parser
     1130 */
     1131enum {
     1132    PARSE_COLLAPSE  = 0x00010000, // treat consecutive delimiters as one
     1133    PARSE_TRIM      = 0x00020000, // trim leading and trailing delimiters
     1134// TODO: COLLAPSE and TRIM seem to always go in pair
     1135    PARSE_GREEDY    = 0x00040000, // last token takes entire remainder of the line
     1136    PARSE_MIN_DIE   = 0x00100000, // die if < min tokens found
     1137    // keep a copy of current line
     1138    PARSE_KEEP_COPY = 0x00200000 * ENABLE_FEATURE_CROND_D,
     1139//  PARSE_ESCAPE    = 0x00400000, // process escape sequences in tokens
     1140    // NORMAL is:
     1141    // * remove leading and trailing delimiters and collapse
     1142    //   multiple delimiters into one
     1143    // * warn and continue if less than mintokens delimiters found
     1144    // * grab everything into last token
     1145    PARSE_NORMAL    = PARSE_COLLAPSE | PARSE_TRIM | PARSE_GREEDY,
     1146};
     1147typedef struct parser_t {
     1148    FILE *fp;
     1149    char *line;
     1150    char *data;
     1151    int lineno;
     1152} parser_t;
     1153parser_t* config_open(const char *filename) FAST_FUNC;
     1154parser_t* config_open2(const char *filename, FILE* FAST_FUNC (*fopen_func)(const char *path)) FAST_FUNC;
     1155/* delims[0] is a comment char (use '\0' to disable), the rest are token delimiters */
     1156int config_read(parser_t *parser, char **tokens, unsigned flags, const char *delims) FAST_FUNC;
     1157#define config_read(parser, tokens, max, min, str, flags) \
     1158    config_read(parser, tokens, ((flags) | (((min) & 0xFF) << 8) | ((max) & 0xFF)), str)
     1159void config_close(parser_t *parser) FAST_FUNC;
     1160
     1161/* Concatenate path and filename to new allocated buffer.
     1162 * Add "/" only as needed (no duplicate "//" are produced).
     1163 * If path is NULL, it is assumed to be "/".
     1164 * filename should not be NULL. */
     1165char *concat_path_file(const char *path, const char *filename) FAST_FUNC;
     1166char *concat_subpath_file(const char *path, const char *filename) FAST_FUNC;
     1167const char *bb_basename(const char *name) FAST_FUNC;
    7601168/* NB: can violate const-ness (similarly to strchr) */
    761 char *last_char_is(const char *s, int c);
    762 
    763 
    764 USE_DESKTOP(long long) int uncompress(int fd_in, int fd_out);
    765 int inflate(int in, int out);
    766 
    767 
    768 int bb_make_directory(char *path, long mode, int flags);
    769 
    770 int get_signum(const char *name);
    771 const char *get_signame(int number);
    772 
    773 char *bb_simplify_path(const char *path);
     1169char *last_char_is(const char *s, int c) FAST_FUNC;
     1170
     1171
     1172int bb_make_directory(char *path, long mode, int flags) FAST_FUNC;
     1173
     1174int get_signum(const char *name) FAST_FUNC;
     1175const char *get_signame(int number) FAST_FUNC;
     1176void print_signames(void) FAST_FUNC;
     1177
     1178char *bb_simplify_path(const char *path) FAST_FUNC;
     1179/* Returns ptr to NUL */
     1180char *bb_simplify_abs_path_inplace(char *path) FAST_FUNC;
    7741181
    7751182#define FAIL_DELAY 3
    776 extern void bb_do_delay(int seconds);
    777 extern void change_identity(const struct passwd *pw);
    778 extern const char *change_identity_e2str(const struct passwd *pw);
    779 extern void run_shell(const char *shell, int loginshell, const char *command, const char **additional_args) ATTRIBUTE_NORETURN;
     1183extern void bb_do_delay(int seconds) FAST_FUNC;
     1184extern void change_identity(const struct passwd *pw) FAST_FUNC;
     1185extern void run_shell(const char *shell, int loginshell, const char *command, const char **additional_args) NORETURN FAST_FUNC;
    7801186#if ENABLE_SELINUX
    781 extern void renew_current_security_context(void);
    782 extern void set_current_security_context(security_context_t sid);
     1187extern void renew_current_security_context(void) FAST_FUNC;
     1188extern void set_current_security_context(security_context_t sid) FAST_FUNC;
    7831189extern context_t set_security_context_component(security_context_t cur_context,
    784                         char *user, char *role, char *type, char *range);
    785 extern void setfscreatecon_or_die(security_context_t scontext);
    786 #endif
    787 extern void selinux_or_die(void);
    788 extern int restricted_shell(const char *shell);
    789 extern void setup_environment(const char *shell, int loginshell, int changeenv, const struct passwd *pw);
    790 extern int correct_password(const struct passwd *pw);
    791 /* Returns a ptr to static storage */
    792 extern char *pw_encrypt(const char *clear, const char *salt);
    793 extern int obscure(const char *old, const char *newval, const struct passwd *pwdp);
    794 extern int index_in_str_array(const char *const string_array[], const char *key);
    795 extern int index_in_strings(const char *strings, const char *key);
    796 extern int index_in_substr_array(const char *const string_array[], const char *key);
    797 extern int index_in_substrings(const char *strings, const char *key);
    798 extern void print_login_issue(const char *issue_file, const char *tty);
    799 extern void print_login_prompt(void);
    800 
     1190                        char *user, char *role, char *type, char *range) FAST_FUNC;
     1191extern void setfscreatecon_or_die(security_context_t scontext) FAST_FUNC;
     1192extern void selinux_preserve_fcontext(int fdesc) FAST_FUNC;
     1193#else
     1194#define selinux_preserve_fcontext(fdesc) ((void)0)
     1195#endif
     1196extern void selinux_or_die(void) FAST_FUNC;
     1197
     1198/* setup_environment:
     1199 * if chdir pw->pw_dir: ok: else if to_tmp == 1: goto /tmp else: goto / or die
     1200 * if clear_env = 1: cd(pw->pw_dir), clear environment, then set
     1201 *   TERM=(old value)
     1202 *   USER=pw->pw_name, LOGNAME=pw->pw_name
     1203 *   PATH=bb_default_[root_]path
     1204 *   HOME=pw->pw_dir
     1205 *   SHELL=shell
     1206 * else if change_env = 1:
     1207 *   if not root (if pw->pw_uid != 0):
     1208 *     USER=pw->pw_name, LOGNAME=pw->pw_name
     1209 *   HOME=pw->pw_dir
     1210 *   SHELL=shell
     1211 * else does nothing
     1212 */
     1213#define SETUP_ENV_CHANGEENV (1 << 0)
     1214#define SETUP_ENV_CLEARENV  (1 << 1)
     1215#define SETUP_ENV_TO_TMP    (1 << 2)
     1216extern void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC;
     1217extern int correct_password(const struct passwd *pw) FAST_FUNC;
     1218/* Returns a malloced string */
     1219#if !ENABLE_USE_BB_CRYPT
     1220#define pw_encrypt(clear, salt, cleanup) pw_encrypt(clear, salt)
     1221#endif
     1222extern char *pw_encrypt(const char *clear, const char *salt, int cleanup) FAST_FUNC;
     1223extern int obscure(const char *old, const char *newval, const struct passwd *pwdp) FAST_FUNC;
    8011224/* rnd is additional random input. New one is returned.
    8021225 * Useful if you call crypt_make_salt many times in a row:
     
    8061229 * (otherwise we risk having same salt generated)
    8071230 */
    808 extern int crypt_make_salt(char *p, int cnt, int rnd);
     1231extern int crypt_make_salt(char *p, int cnt, int rnd) FAST_FUNC;
    8091232
    8101233/* Returns number of lines changed, or -1 on error */
    811 extern int update_passwd(const char *filename, const char *username,
    812             const char *new_pw);
    813 
     1234#if !(ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP)
     1235#define update_passwd(filename, username, data, member) \
     1236    update_passwd(filename, username, data)
     1237#endif
     1238extern int update_passwd(const char *filename,
     1239        const char *username,
     1240        const char *data,
     1241        const char *member) FAST_FUNC;
     1242
     1243int index_in_str_array(const char *const string_array[], const char *key) FAST_FUNC;
     1244int index_in_strings(const char *strings, const char *key) FAST_FUNC;
     1245int index_in_substr_array(const char *const string_array[], const char *key) FAST_FUNC;
     1246int index_in_substrings(const char *strings, const char *key) FAST_FUNC;
     1247const char *nth_string(const char *strings, int n) FAST_FUNC;
     1248
     1249extern void print_login_issue(const char *issue_file, const char *tty) FAST_FUNC;
     1250extern void print_login_prompt(void) FAST_FUNC;
     1251
     1252char *xmalloc_ttyname(int fd) FAST_FUNC RETURNS_MALLOC;
    8141253/* NB: typically you want to pass fd 0, not 1. Think 'applet | grep something' */
    815 int get_terminal_width_height(int fd, int *width, int *height);
    816 
    817 int ioctl_or_perror(int fd, int request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
    818 void ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
     1254int get_terminal_width_height(int fd, unsigned *width, unsigned *height) FAST_FUNC;
     1255
     1256int tcsetattr_stdin_TCSANOW(const struct termios *tp) FAST_FUNC;
     1257
     1258/* NB: "unsigned request" is crucial! "int request" will break some arches! */
     1259int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC;
     1260int ioctl_or_perror_and_die(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC;
    8191261#if ENABLE_IOCTL_HEX2STR_ERROR
    820 int bb_ioctl_or_warn(int fd, int request, void *argp, const char *ioctl_name);
    821 void bb_xioctl(int fd, int request, void *argp, const char *ioctl_name);
     1262int bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC;
     1263int bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name) FAST_FUNC;
    8221264#define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp,#request)
    8231265#define xioctl(fd,request,argp)        bb_xioctl(fd,request,argp,#request)
    8241266#else
    825 int bb_ioctl_or_warn(int fd, int request, void *argp);
    826 void bb_xioctl(int fd, int request, void *argp);
     1267int bb_ioctl_or_warn(int fd, unsigned request, void *argp) FAST_FUNC;
     1268int bb_xioctl(int fd, unsigned request, void *argp) FAST_FUNC;
    8271269#define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp)
    8281270#define xioctl(fd,request,argp)        bb_xioctl(fd,request,argp)
    8291271#endif
    8301272
    831 char *is_in_ino_dev_hashtable(const struct stat *statbuf);
    832 void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name);
    833 void reset_ino_dev_hashtable(void);
     1273char *is_in_ino_dev_hashtable(const struct stat *statbuf) FAST_FUNC;
     1274void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name) FAST_FUNC;
     1275void reset_ino_dev_hashtable(void) FAST_FUNC;
    8341276#ifdef __GLIBC__
    8351277/* At least glibc has horrendously large inline for this, so wrap it */
    836 unsigned long long bb_makedev(unsigned int major, unsigned int minor);
     1278unsigned long long bb_makedev(unsigned int major, unsigned int minor) FAST_FUNC;
    8371279#undef makedev
    8381280#define makedev(a,b) bb_makedev(a,b)
     
    8401282
    8411283
     1284/* "Keycodes" that report an escape sequence.
     1285 * We use something which fits into signed char,
     1286 * yet doesn't represent any valid Unicode character.
     1287 * Also, -1 is reserved for error indication and we don't use it. */
     1288enum {
     1289    KEYCODE_UP       =  -2,
     1290    KEYCODE_DOWN     =  -3,
     1291    KEYCODE_RIGHT    =  -4,
     1292    KEYCODE_LEFT     =  -5,
     1293    KEYCODE_HOME     =  -6,
     1294    KEYCODE_END      =  -7,
     1295    KEYCODE_INSERT   =  -8,
     1296    KEYCODE_DELETE   =  -9,
     1297    KEYCODE_PAGEUP   = -10,
     1298    KEYCODE_PAGEDOWN = -11,
     1299
     1300    KEYCODE_CTRL_UP    = KEYCODE_UP    & ~0x40,
     1301    KEYCODE_CTRL_DOWN  = KEYCODE_DOWN  & ~0x40,
     1302    KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40,
     1303    KEYCODE_CTRL_LEFT  = KEYCODE_LEFT  & ~0x40,
     1304#if 0
     1305    KEYCODE_FUN1     = -12,
     1306    KEYCODE_FUN2     = -13,
     1307    KEYCODE_FUN3     = -14,
     1308    KEYCODE_FUN4     = -15,
     1309    KEYCODE_FUN5     = -16,
     1310    KEYCODE_FUN6     = -17,
     1311    KEYCODE_FUN7     = -18,
     1312    KEYCODE_FUN8     = -19,
     1313    KEYCODE_FUN9     = -20,
     1314    KEYCODE_FUN10    = -21,
     1315    KEYCODE_FUN11    = -22,
     1316    KEYCODE_FUN12    = -23,
     1317#endif
     1318    KEYCODE_CURSOR_POS = -0x100, /* 0xfff..fff00 */
     1319    /* How long is the longest ESC sequence we know?
     1320     * We want it big enough to be able to contain
     1321     * cursor position sequence "ESC [ 9999 ; 9999 R"
     1322     */
     1323    KEYCODE_BUFFER_SIZE = 16
     1324};
     1325/* Note: fd may be in blocking or non-blocking mode, both make sense.
     1326 * For one, less uses non-blocking mode.
     1327 * Only the first read syscall inside read_key may block indefinitely
     1328 * (unless fd is in non-blocking mode),
     1329 * subsequent reads will time out after a few milliseconds.
     1330 * Return of -1 means EOF or error (errno == 0 on EOF).
     1331 * buffer[0] is used as a counter of buffered chars and must be 0
     1332 * on first call.
     1333 * timeout:
     1334 * -2: do not poll for input;
     1335 * -1: poll(-1) (i.e. block);
     1336 * >=0: poll for TIMEOUT milliseconds, return -1/EAGAIN on timeout
     1337 */
     1338int64_t read_key(int fd, char *buffer, int timeout) FAST_FUNC;
     1339void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC;
     1340
     1341
    8421342#if ENABLE_FEATURE_EDITING
    8431343/* It's NOT just ENABLEd or disabled. It's a number: */
    844 #ifdef CONFIG_FEATURE_EDITING_HISTORY
    845 #define MAX_HISTORY (CONFIG_FEATURE_EDITING_HISTORY + 0)
    846 #else
    847 #define MAX_HISTORY 0
    848 #endif
     1344# ifdef CONFIG_FEATURE_EDITING_HISTORY
     1345#  define MAX_HISTORY (CONFIG_FEATURE_EDITING_HISTORY + 0)
     1346# else
     1347#  define MAX_HISTORY 0
     1348# endif
    8491349typedef struct line_input_t {
    8501350    int flags;
    8511351    const char *path_lookup;
    852 #if MAX_HISTORY
     1352# if MAX_HISTORY
    8531353    int cnt_history;
    8541354    int cur_history;
    855     USE_FEATURE_EDITING_SAVEHISTORY(const char *hist_file;)
     1355#  if ENABLE_FEATURE_EDITING_SAVEHISTORY
     1356    unsigned cnt_history_in_file;
     1357    const char *hist_file;
     1358#  endif
    8561359    char *history[MAX_HISTORY + 1];
    857 #endif
     1360# endif
    8581361} line_input_t;
    8591362enum {
     
    8661369    FOR_SHELL = DO_HISTORY | SAVE_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION,
    8671370};
    868 line_input_t *new_line_input_t(int flags);
    869 int read_line_input(const char* prompt, char* command, int maxsize, line_input_t *state);
    870 #else
    871 int read_line_input(const char* prompt, char* command, int maxsize);
     1371line_input_t *new_line_input_t(int flags) FAST_FUNC;
     1372/* So far static: void free_line_input_t(line_input_t *n) FAST_FUNC; */
     1373/* maxsize must be >= 2.
     1374 * Returns:
     1375 * -1 on read errors or EOF, or on bare Ctrl-D,
     1376 * 0  on ctrl-C (the line entered is still returned in 'command'),
     1377 * >0 length of input string, including terminating '\n'
     1378 */
     1379int read_line_input(const char* prompt, char* command, int maxsize, line_input_t *state) FAST_FUNC;
     1380#else
     1381#define MAX_HISTORY 0
     1382int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC;
    8721383#define read_line_input(prompt, command, maxsize, state) \
    8731384    read_line_input(prompt, command, maxsize)
     
    8761387
    8771388#ifndef COMM_LEN
    878 #ifdef TASK_COMM_LEN
     1389# ifdef TASK_COMM_LEN
    8791390enum { COMM_LEN = TASK_COMM_LEN };
    880 #else
     1391# else
    8811392/* synchronize with sizeof(task_struct.comm) in /usr/include/linux/sched.h */
    8821393enum { COMM_LEN = 16 };
    883 #endif
    884 #endif
    885 typedef struct {
     1394# endif
     1395#endif
     1396
     1397struct smaprec {
     1398    unsigned long mapped_rw;
     1399    unsigned long mapped_ro;
     1400    unsigned long shared_clean;
     1401    unsigned long shared_dirty;
     1402    unsigned long private_clean;
     1403    unsigned long private_dirty;
     1404    unsigned long stack;
     1405    unsigned long smap_pss, smap_swap;
     1406    unsigned long smap_size;
     1407    unsigned long smap_start;
     1408    char smap_mode[5];
     1409    char *smap_name;
     1410};
     1411
     1412#if !ENABLE_PMAP
     1413#define procps_read_smaps(pid, total, cb, data) \
     1414    procps_read_smaps(pid, total)
     1415#endif
     1416int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
     1417              void (*cb)(struct smaprec *, void *), void *data);
     1418
     1419typedef struct procps_status_t {
    8861420    DIR *dir;
     1421    IF_FEATURE_SHOW_THREADS(DIR *task_dir;)
     1422    uint8_t shift_pages_to_bytes;
     1423    uint8_t shift_pages_to_kb;
    8871424/* Fields are set to 0/NULL if failed to determine (or not requested) */
    888     /*char *cmd;*/
     1425    uint16_t argv_len;
    8891426    char *argv0;
    890     /*char *exe;*/
    891     USE_SELINUX(char *context;)
     1427    char *exe;
     1428    IF_SELINUX(char *context;)
    8921429    /* Everything below must contain no ptrs to malloc'ed data:
    8931430     * it is memset(0) for each process in procps_scan() */
    894     unsigned vsz, rss; /* we round it to kbytes */
     1431    unsigned long vsz, rss; /* we round it to kbytes */
    8951432    unsigned long stime, utime;
     1433    unsigned long start_time;
    8961434    unsigned pid;
    8971435    unsigned ppid;
     
    9001438    unsigned uid;
    9011439    unsigned gid;
     1440#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
     1441    unsigned ruid;
     1442    unsigned rgid;
     1443    int niceness;
     1444#endif
    9021445    unsigned tty_major,tty_minor;
     1446#if ENABLE_FEATURE_TOPMEM
     1447    struct smaprec smaps;
     1448#endif
    9031449    char state[4];
    9041450    /* basename of executable in exec(2), read from /proc/N/stat
     
    9071453    char comm[COMM_LEN];
    9081454    /* user/group? - use passwd/group parsing functions */
     1455#if ENABLE_FEATURE_TOP_SMP_PROCESS
     1456    int last_seen_on_cpu;
     1457#endif
    9091458} procps_status_t;
     1459/* flag bits for procps_scan(xx, flags) calls */
    9101460enum {
    9111461    PSSCAN_PID      = 1 << 0,
     
    9171467    /* PSSCAN_CMD      = 1 << 6, - use read_cmdline instead */
    9181468    PSSCAN_ARGV0    = 1 << 7,
    919     /* PSSCAN_EXE      = 1 << 8, - not implemented */
     1469    PSSCAN_EXE      = 1 << 8,
    9201470    PSSCAN_STATE    = 1 << 9,
    9211471    PSSCAN_VSZ      = 1 << 10,
     
    9241474    PSSCAN_UTIME    = 1 << 13,
    9251475    PSSCAN_TTY      = 1 << 14,
    926     USE_SELINUX(PSSCAN_CONTEXT  = 1 << 15,)
     1476    PSSCAN_SMAPS    = (1 << 15) * ENABLE_FEATURE_TOPMEM,
     1477    /* NB: used by find_pid_by_name(). Any applet using it
     1478     * needs to be mentioned here. */
     1479    PSSCAN_ARGVN    = (1 << 16) * (ENABLE_KILLALL
     1480                || ENABLE_PGREP || ENABLE_PKILL
     1481                || ENABLE_PIDOF
     1482                || ENABLE_SESTATUS
     1483                ),
     1484    PSSCAN_CONTEXT  = (1 << 17) * ENABLE_SELINUX,
     1485    PSSCAN_START_TIME = 1 << 18,
     1486    PSSCAN_CPU      = (1 << 19) * ENABLE_FEATURE_TOP_SMP_PROCESS,
     1487    PSSCAN_NICE     = (1 << 20) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
     1488    PSSCAN_RUIDGID  = (1 << 21) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
     1489    PSSCAN_TASKS    = (1 << 22) * ENABLE_FEATURE_SHOW_THREADS,
    9271490    /* These are all retrieved from proc/NN/stat in one go: */
    9281491    PSSCAN_STAT     = PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID
    929                     | PSSCAN_COMM | PSSCAN_STATE
    930                     | PSSCAN_VSZ | PSSCAN_RSS
    931             | PSSCAN_STIME | PSSCAN_UTIME
    932             | PSSCAN_TTY,
    933 };
    934 procps_status_t* alloc_procps_scan(int flags);
    935 void free_procps_scan(procps_status_t* sp);
    936 procps_status_t* procps_scan(procps_status_t* sp, int flags);
    937 /* Format cmdline (up to col chars) into char buf[col+1] */
     1492    /**/            | PSSCAN_COMM | PSSCAN_STATE
     1493    /**/            | PSSCAN_VSZ | PSSCAN_RSS
     1494    /**/            | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_START_TIME
     1495    /**/            | PSSCAN_TTY | PSSCAN_NICE
     1496    /**/            | PSSCAN_CPU
     1497};
     1498//procps_status_t* alloc_procps_scan(void) FAST_FUNC;
     1499void free_procps_scan(procps_status_t* sp) FAST_FUNC;
     1500procps_status_t* procps_scan(procps_status_t* sp, int flags) FAST_FUNC;
     1501/* Format cmdline (up to col chars) into char buf[size] */
    9381502/* Puts [comm] if cmdline is empty (-> process is a kernel thread) */
    939 void read_cmdline(char *buf, int col, unsigned pid, const char *comm);
    940 pid_t *find_pid_by_name(const char* procName);
    941 pid_t *pidlist_reverse(pid_t *pidList);
     1503void read_cmdline(char *buf, int size, unsigned pid, const char *comm) FAST_FUNC;
     1504pid_t *find_pid_by_name(const char* procName) FAST_FUNC;
     1505pid_t *pidlist_reverse(pid_t *pidList) FAST_FUNC;
     1506int starts_with_cpu(const char *str) FAST_FUNC;
     1507unsigned get_cpu_count(void) FAST_FUNC;
    9421508
    9431509
    9441510extern const char bb_uuenc_tbl_base64[];
    9451511extern const char bb_uuenc_tbl_std[];
    946 void bb_uuencode(char *store, const void *s, int length, const char *tbl);
    947 
    948 typedef struct sha1_ctx_t {
    949     uint32_t count[2];
    950     uint32_t hash[5];
    951     uint32_t wbuf[16];
    952 } sha1_ctx_t;
    953 void sha1_begin(sha1_ctx_t *ctx);
    954 void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx);
    955 void *sha1_end(void *resbuf, sha1_ctx_t *ctx);
     1512void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC;
     1513enum {
     1514    BASE64_FLAG_UU_STOP = 0x100,
     1515    /* Sign-extends to a value which never matches fgetc result: */
     1516    BASE64_FLAG_NO_STOP_CHAR = 0x80,
     1517};
     1518void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags);
    9561519
    9571520typedef struct md5_ctx_t {
    958     uint32_t A;
    959     uint32_t B;
    960     uint32_t C;
    961     uint32_t D;
    962     uint64_t total;
    963     uint32_t buflen;
    964     char buffer[128];
     1521    uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */
     1522    void (*process_block)(struct md5_ctx_t*) FAST_FUNC;
     1523    uint64_t total64;    /* must be directly before hash[] */
     1524    uint32_t hash[8];    /* 4 elements for md5, 5 for sha1, 8 for sha256 */
    9651525} md5_ctx_t;
    966 void md5_begin(md5_ctx_t *ctx);
    967 void md5_hash(const void *data, size_t length, md5_ctx_t *ctx);
    968 void *md5_end(void *resbuf, md5_ctx_t *ctx);
    969 
    970 uint32_t *crc32_filltable(uint32_t *tbl256, int endian);
    971 
    972 
    973 enum {  /* DO NOT CHANGE THESE VALUES!  cp.c, mv.c, install.c depend on them. */
    974     FILEUTILS_PRESERVE_STATUS = 1,
    975     FILEUTILS_DEREFERENCE = 2,
    976     FILEUTILS_RECUR = 4,
    977     FILEUTILS_FORCE = 8,
    978     FILEUTILS_INTERACTIVE = 0x10,
    979     FILEUTILS_MAKE_HARDLINK = 0x20,
    980     FILEUTILS_MAKE_SOFTLINK = 0x40,
    981 #if ENABLE_SELINUX
    982     FILEUTILS_PRESERVE_SECURITY_CONTEXT = 0x80,
    983     FILEUTILS_SET_SECURITY_CONTEXT = 0x100
    984 #endif
    985 };
    986 
    987 #define FILEUTILS_CP_OPTSTR "pdRfils" USE_SELINUX("c")
    988 extern const struct bb_applet *current_applet;
     1526typedef struct md5_ctx_t sha1_ctx_t;
     1527typedef struct md5_ctx_t sha256_ctx_t;
     1528typedef struct sha512_ctx_t {
     1529    uint64_t total64[2];  /* must be directly before hash[] */
     1530    uint64_t hash[8];
     1531    uint8_t wbuffer[128]; /* always correctly aligned for uint64_t */
     1532} sha512_ctx_t;
     1533void md5_begin(md5_ctx_t *ctx) FAST_FUNC;
     1534void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC;
     1535void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC;
     1536void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;
     1537#define sha1_hash md5_hash
     1538void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC;
     1539void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
     1540#define sha256_hash md5_hash
     1541#define sha256_end  sha1_end
     1542void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
     1543void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
     1544void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
     1545
     1546extern uint32_t *global_crc32_table;
     1547uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;
     1548uint32_t crc32_block_endian1(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC;
     1549uint32_t crc32_block_endian0(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC;
     1550
     1551typedef struct masks_labels_t {
     1552    const char *labels;
     1553    const int masks[];
     1554} masks_labels_t;
     1555int print_flags_separated(const int *masks, const char *labels,
     1556        int flags, const char *separator) FAST_FUNC;
     1557int print_flags(const masks_labels_t *ml, int flags) FAST_FUNC;
     1558
     1559typedef struct bb_progress_t {
     1560    off_t lastsize;
     1561    unsigned lastupdate_sec;
     1562    unsigned start_sec;
     1563    smallint inited;
     1564} bb_progress_t;
     1565
     1566void bb_progress_init(bb_progress_t *p) FAST_FUNC;
     1567void bb_progress_update(bb_progress_t *p, const char *curfile,
     1568            off_t beg_range, off_t transferred,
     1569            off_t totalsize) FAST_FUNC;
     1570
    9891571extern const char *applet_name;
    990 /* "BusyBox vN.N.N (timestamp or extra_vestion)" */
     1572
     1573/* Some older linkers don't perform string merging, we used to have common strings
     1574 * as global arrays to do it by hand. But:
     1575 * (1) newer linkers do it themselves,
     1576 * (2) however, they DONT merge string constants with global arrays,
     1577 * even if the value is the same (!). Thus global arrays actually
     1578 * increased size a bit: for example, "/etc/passwd" string from libc
     1579 * wasn't merged with bb_path_passwd_file[] array!
     1580 * Therefore now we use #defines.
     1581 */
     1582/* "BusyBox vN.N.N (timestamp or extra_version)" */
    9911583extern const char bb_banner[];
    9921584extern const char bb_msg_memory_exhausted[];
    9931585extern const char bb_msg_invalid_date[];
    994 extern const char bb_msg_read_error[];
    995 extern const char bb_msg_write_error[];
     1586#define bb_msg_read_error "read error"
     1587#define bb_msg_write_error "write error"
    9961588extern const char bb_msg_unknown[];
    9971589extern const char bb_msg_can_not_create_raw_socket[];
    9981590extern const char bb_msg_perm_denied_are_you_root[];
     1591extern const char bb_msg_you_must_be_root[];
    9991592extern const char bb_msg_requires_arg[];
    10001593extern const char bb_msg_invalid_arg[];
     
    10021595extern const char bb_msg_standard_output[];
    10031596
    1004 extern const char bb_str_default[];
    10051597/* NB: (bb_hexdigits_upcase[i] | 0x20) -> lowercase hex digit */
    10061598extern const char bb_hexdigits_upcase[];
    10071599
    1008 extern const char bb_path_mtab_file[];
    1009 extern const char bb_path_passwd_file[];
    1010 extern const char bb_path_shadow_file[];
    1011 extern const char bb_path_gshadow_file[];
    1012 extern const char bb_path_group_file[];
    1013 extern const char bb_path_motd_file[];
    10141600extern const char bb_path_wtmp_file[];
    1015 extern const char bb_dev_null[];
     1601
     1602/* Busybox mount uses either /proc/mounts or /etc/mtab to
     1603 * get the list of currently mounted filesystems */
     1604#define bb_path_mtab_file IF_FEATURE_MTAB_SUPPORT("/etc/mtab")IF_NOT_FEATURE_MTAB_SUPPORT("/proc/mounts")
     1605
     1606#define bb_path_passwd_file "/etc/passwd"
     1607#define bb_path_shadow_file "/etc/shadow"
     1608#define bb_path_gshadow_file "/etc/gshadow"
     1609#define bb_path_group_file "/etc/group"
     1610
     1611#define bb_path_motd_file "/etc/motd"
     1612
     1613#define bb_dev_null "/dev/null"
    10161614extern const char bb_busybox_exec_path[];
    10171615/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
     
    10251623
    10261624
    1027 #ifndef BUFSIZ
    1028 #define BUFSIZ 4096
    1029 #endif
    10301625/* Providing hard guarantee on minimum size (think of BUFSIZ == 128) */
    10311626enum { COMMON_BUFSIZE = (BUFSIZ >= 256*sizeof(void*) ? BUFSIZ+1 : 256*sizeof(void*)) };
     
    10361631/* '*const' ptr makes gcc optimize code much better.
    10371632 * Magic prevents ptr_to_globals from going into rodata.
    1038  * If you want to assign a value, use PTR_TO_GLOBALS = xxx */
     1633 * If you want to assign a value, use SET_PTR_TO_GLOBALS(x) */
    10391634extern struct globals *const ptr_to_globals;
    1040 #define PTR_TO_GLOBALS (*(struct globals**)&ptr_to_globals)
    1041 
     1635/* At least gcc 3.4.6 on mipsel system needs optimization barrier */
     1636#define barrier() __asm__ __volatile__("":::"memory")
     1637#define SET_PTR_TO_GLOBALS(x) do { \
     1638    (*(struct globals**)&ptr_to_globals) = (void*)(x); \
     1639    barrier(); \
     1640} while (0)
    10421641
    10431642/* You can change LIBBB_DEFAULT_LOGIN_SHELL, but don't use it,
     
    10451644 * If you change LIBBB_DEFAULT_LOGIN_SHELL,
    10461645 * don't forget to change increment constant. */
    1047 #define LIBBB_DEFAULT_LOGIN_SHELL      "-/bin/sh"
     1646#define LIBBB_DEFAULT_LOGIN_SHELL  "-/bin/sh"
    10481647extern const char bb_default_login_shell[];
    10491648/* "/bin/sh" */
    1050 #define DEFAULT_SHELL     (bb_default_login_shell+1)
     1649#define DEFAULT_SHELL              (bb_default_login_shell+1)
    10511650/* "sh" */
    1052 #define DEFAULT_SHELL_SHORT_NAME     (bb_default_login_shell+6)
    1053 
    1054 
    1055 #if ENABLE_FEATURE_DEVFS
     1651#define DEFAULT_SHELL_SHORT_NAME   (bb_default_login_shell+6)
     1652
     1653/* The following devices are the same on all systems.  */
     1654#define CURRENT_TTY "/dev/tty"
     1655#define DEV_CONSOLE "/dev/console"
     1656
     1657#if defined(__FreeBSD_kernel__)
     1658# define CURRENT_VC CURRENT_TTY
     1659# define VC_1 "/dev/ttyv0"
     1660# define VC_2 "/dev/ttyv1"
     1661# define VC_3 "/dev/ttyv2"
     1662# define VC_4 "/dev/ttyv3"
     1663# define VC_5 "/dev/ttyv4"
     1664# define VC_FORMAT "/dev/ttyv%d"
     1665#elif defined(__GNU__)
     1666# define CURRENT_VC CURRENT_TTY
     1667# define VC_1 "/dev/tty1"
     1668# define VC_2 "/dev/tty2"
     1669# define VC_3 "/dev/tty3"
     1670# define VC_4 "/dev/tty4"
     1671# define VC_5 "/dev/tty5"
     1672# define VC_FORMAT "/dev/tty%d"
     1673#elif ENABLE_FEATURE_DEVFS
     1674/*Linux, obsolete devfs names */
    10561675# define CURRENT_VC "/dev/vc/0"
    10571676# define VC_1 "/dev/vc/1"
     
    10601679# define VC_4 "/dev/vc/4"
    10611680# define VC_5 "/dev/vc/5"
    1062 #if defined(__sh__) || defined(__H8300H__) || defined(__H8300S__)
    1063 /* Yes, this sucks, but both SH (including sh64) and H8 have a SCI(F) for their
    1064    respective serial ports .. as such, we can't use the common device paths for
    1065    these. -- PFM */
    1066 #  define SC_0 "/dev/ttsc/0"
    1067 #  define SC_1 "/dev/ttsc/1"
    1068 #  define SC_FORMAT "/dev/ttsc/%d"
    1069 #else
    1070 #  define SC_0 "/dev/tts/0"
    1071 #  define SC_1 "/dev/tts/1"
    1072 #  define SC_FORMAT "/dev/tts/%d"
    1073 #endif
    10741681# define VC_FORMAT "/dev/vc/%d"
    10751682# define LOOP_FORMAT "/dev/loop/%d"
     
    10781685# define FB_0 "/dev/fb/0"
    10791686#else
     1687/*Linux, normal names */
    10801688# define CURRENT_VC "/dev/tty0"
    10811689# define VC_1 "/dev/tty1"
     
    10841692# define VC_4 "/dev/tty4"
    10851693# define VC_5 "/dev/tty5"
    1086 #if defined(__sh__) || defined(__H8300H__) || defined(__H8300S__)
    1087 #  define SC_0 "/dev/ttySC0"
    1088 #  define SC_1 "/dev/ttySC1"
    1089 #  define SC_FORMAT "/dev/ttySC%d"
    1090 #else
    1091 #  define SC_0 "/dev/ttyS0"
    1092 #  define SC_1 "/dev/ttyS1"
    1093 #  define SC_FORMAT "/dev/ttyS%d"
    1094 #endif
    10951694# define VC_FORMAT "/dev/tty%d"
    10961695# define LOOP_FORMAT "/dev/loop%d"
     
    11001699#endif
    11011700
    1102 /* The following devices are the same on devfs and non-devfs systems.  */
    1103 #define CURRENT_TTY "/dev/tty"
    1104 #define DEV_CONSOLE "/dev/console"
    1105 
    1106 
    1107 #ifndef RB_POWER_OFF
    1108 /* Stop system and switch power off if possible.  */
    1109 #define RB_POWER_OFF   0x4321fedc
    1110 #endif
    1111 
    1112 /* Make sure we call functions instead of macros.  */
     1701
     1702#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))
     1703
     1704
     1705/* We redefine ctype macros. Unicode-correct handling of char types
     1706 * can't be done with such byte-oriented operations anyway,
     1707 * we don't lose anything.
     1708 */
    11131709#undef isalnum
    11141710#undef isalpha
     
    11161712#undef isblank
    11171713#undef iscntrl
     1714#undef isdigit
    11181715#undef isgraph
    11191716#undef islower
     
    11231720#undef isupper
    11241721#undef isxdigit
    1125 
    1126 /* This one is more efficient - we save ~400 bytes */
    1127 #undef isdigit
    1128 #define isdigit(a) ((unsigned)((a) - '0') <= 9)
    1129 
    1130 
    1131 #ifdef DMALLOC
    1132 #include <dmalloc.h>
    1133 #endif
    1134 
    1135 
    1136 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
    1137 
    1138 #endif /* __LIBBUSYBOX_H__ */
     1722#undef toupper
     1723#undef tolower
     1724
     1725/* We save ~500 bytes on isdigit alone.
     1726 * BTW, x86 likes (unsigned char) cast more than (unsigned). */
     1727
     1728/* These work the same for ASCII and Unicode,
     1729 * assuming no one asks "is this a *Unicode* letter?" using isalpha(letter) */
     1730#define isascii(a) ((unsigned char)(a) <= 0x7f)
     1731#define isdigit(a) ((unsigned char)((a) - '0') <= 9)
     1732#define isupper(a) ((unsigned char)((a) - 'A') <= ('Z' - 'A'))
     1733#define islower(a) ((unsigned char)((a) - 'a') <= ('z' - 'a'))
     1734#define isalpha(a) ((unsigned char)(((a)|0x20) - 'a') <= ('z' - 'a'))
     1735#define isblank(a) ({ unsigned char bb__isblank = (a); bb__isblank == ' ' || bb__isblank == '\t'; })
     1736#define iscntrl(a) ({ unsigned char bb__iscntrl = (a); bb__iscntrl < ' ' || bb__iscntrl == 0x7f; })
     1737/* In POSIX/C locale isspace is only these chars: "\t\n\v\f\r" and space.
     1738 * "\t\n\v\f\r" happen to have ASCII codes 9,10,11,12,13.
     1739 */
     1740#define isspace(a) ({ unsigned char bb__isspace = (a) - 9; bb__isspace == (' ' - 9) || bb__isspace <= (13 - 9); })
     1741// Unsafe wrt NUL: #define ispunct(a) (strchr("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", (a)) != NULL)
     1742#define ispunct(a) (strchrnul("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", (a))[0])
     1743// Bigger code: #define isalnum(a) ({ unsigned char bb__isalnum = (a) - '0'; bb__isalnum <= 9 || ((bb__isalnum - ('A' - '0')) & 0xdf) <= 25; })
     1744#define isalnum(a) bb_ascii_isalnum(a)
     1745static ALWAYS_INLINE int bb_ascii_isalnum(unsigned char a)
     1746{
     1747    unsigned char b = a - '0';
     1748    if (b <= 9)
     1749        return (b <= 9);
     1750    b = (a|0x20) - 'a';
     1751    return b <= 'z' - 'a';
     1752}
     1753#define isxdigit(a) bb_ascii_isxdigit(a)
     1754static ALWAYS_INLINE int bb_ascii_isxdigit(unsigned char a)
     1755{
     1756    unsigned char b = a - '0';
     1757    if (b <= 9)
     1758        return (b <= 9);
     1759    b = (a|0x20) - 'a';
     1760    return b <= 'f' - 'a';
     1761}
     1762#define toupper(a) bb_ascii_toupper(a)
     1763static ALWAYS_INLINE unsigned char bb_ascii_toupper(unsigned char a)
     1764{
     1765    unsigned char b = a - 'a';
     1766    if (b <= ('z' - 'a'))
     1767        a -= 'a' - 'A';
     1768    return a;
     1769}
     1770#define tolower(a) bb_ascii_tolower(a)
     1771static ALWAYS_INLINE unsigned char bb_ascii_tolower(unsigned char a)
     1772{
     1773    unsigned char b = a - 'A';
     1774    if (b <= ('Z' - 'A'))
     1775        a += 'a' - 'A';
     1776    return a;
     1777}
     1778
     1779/* In ASCII and Unicode, these are likely to be very different.
     1780 * Let's prevent ambiguous usage from the start */
     1781#define isgraph(a) isgraph_is_ambiguous_dont_use(a)
     1782#define isprint(a) isprint_is_ambiguous_dont_use(a)
     1783/* NB: must not treat EOF as isgraph or isprint */
     1784#define isgraph_asciionly(a) ((unsigned)((a) - 0x21) <= 0x7e - 0x21)
     1785#define isprint_asciionly(a) ((unsigned)((a) - 0x20) <= 0x7e - 0x20)
     1786
     1787
     1788POP_SAVED_FUNCTION_VISIBILITY
     1789
     1790#endif
Note: See TracChangeset for help on using the changeset viewer.