*: add -Wunused-parameter; fix resulting breakage
[oweals/busybox.git] / include / libbb.h
index ccfe1b7052ee76323bcf5d21725b46138e3b7370..ee1ef518e329f9f2a0dcb4d363a5c5ae9c794b9d 100644 (file)
@@ -30,7 +30,6 @@
 #include <sys/mman.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
-#include <sys/statfs.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <mntent.h>
 #endif
 
+#ifdef HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+
 #if ENABLE_SELINUX
 #include <selinux/selinux.h>
 #include <selinux/context.h>
@@ -234,6 +237,7 @@ extern int recursive_action(const char *fileName, unsigned flags,
        int (*dirAction) (const char *fileName, struct stat* statbuf, void* userData, int depth),
        void* userData, unsigned depth);
 extern int device_open(const char *device, int mode);
+extern int getpty(char *line, int size);
 extern int get_console_fd(void);
 extern char *find_block_device(const char *path);
 /* bb_copyfd_XX print read/write errors and return -1 if they occur */
@@ -271,19 +275,56 @@ char *xrealloc_getcwd_or_warn(char *cwd);
 
 char *xmalloc_follow_symlinks(const char *path);
 
-//TODO: signal(sid, f) is the same? then why?
-extern void sig_catch(int,void (*)(int));
-//#define sig_ignore(s) (sig_catch((s), SIG_IGN))
-//#define sig_uncatch(s) (sig_catch((s), SIG_DFL))
-extern void sig_block(int);
-extern void sig_unblock(int);
-/* UNUSED: extern void sig_blocknone(void); */
-extern void sig_pause(void);
+
+enum {
+       /* bb_signals(BB_SIGS_FATAL, handler) catches all signals which
+        * otherwise would kill us, except for those resulting from bugs:
+        * SIGSEGV, SIGILL, SIGFPE.
+        * Other fatal signals not included (TODO?):
+        * SIGBUS   Bus error (bad memory access)
+        * SIGPOLL  Pollable event. Synonym of SIGIO
+        * SIGPROF  Profiling timer expired
+        * SIGSYS   Bad argument to routine
+        * SIGTRAP  Trace/breakpoint trap
+        */
+       BB_SIGS_FATAL = 0
+               + (1 << SIGHUP)
+               + (1 << SIGINT)
+               + (1 << SIGTERM)
+               + (1 << SIGPIPE)   // Write to pipe with no readers
+               + (1 << SIGQUIT)   // Quit from keyboard
+               + (1 << SIGABRT)   // Abort signal from abort(3)
+               + (1 << SIGALRM)   // Timer signal from alarm(2)
+               + (1 << SIGVTALRM) // Virtual alarm clock
+               + (1 << SIGXCPU)   // CPU time limit exceeded
+               + (1 << SIGXFSZ)   // File size limit exceeded
+               + (1 << SIGUSR1)   // Yes kids, these are also fatal!
+               + (1 << SIGUSR2)
+               + 0,
+};
+void bb_signals(int sigs, void (*f)(int));
+/* Unlike signal() and bb_signals, sets handler with sigaction()
+ * and in a way that while signal handler is run, no other signals
+ * will be blocked: */
+void bb_signals_recursive(int sigs, void (*f)(int));
+/* syscalls like read() will be interrupted with EINTR: */
+void signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int));
+/* syscalls like read() won't be interrupted (though select/poll will be): */
+void signal_SA_RESTART_empty_mask(int sig, void (*handler)(int));
+void wait_for_any_sig(void);
+void kill_myself_with_sig(int sig) ATTRIBUTE_NORETURN;
+void sig_block(int sig);
+void sig_unblock(int sig);
+/* Will do sigaction(signum, act, NULL): */
+int sigaction_set(int sig, const struct sigaction *act);
+/* SIG_BLOCK/SIG_UNBLOCK all signals: */
+int sigprocmask_allsigs(int how);
 
 
 void xsetgid(gid_t gid);
 void xsetuid(uid_t uid);
 void xchdir(const char *path);
+void xchroot(const char *path);
 void xsetenv(const char *key, const char *value);
 void xunlink(const char *pathname);
 void xstat(const char *pathname, struct stat *buf);
@@ -291,10 +332,17 @@ int xopen(const char *pathname, int flags);
 int xopen3(const char *pathname, int flags, int mode);
 int open_or_warn(const char *pathname, int flags);
 int open3_or_warn(const char *pathname, int flags, int mode);
-void xpipe(int filedes[2]);
+void xrename(const char *oldpath, const char *newpath);
+int rename_or_warn(const char *oldpath, const char *newpath);
 off_t xlseek(int fd, off_t offset, int whence);
 off_t fdlength(int fd);
 
+void xpipe(int filedes[2]);
+/* In this form code with pipes is much more readable */
+struct fd_pair { int rd; int wr; };
+#define piped_pair(pair)  pipe(&((pair).rd))
+#define xpiped_pair(pair) xpipe(&((pair).rd))
+
 /* Useful for having small structure members/global variables */
 typedef int8_t socktype_t;
 typedef int8_t family_t;
@@ -311,8 +359,12 @@ struct BUG_too_small {
                        | AF_INET
                        | AF_INET6
                        | AF_UNIX
+#ifdef AF_PACKET
                        | AF_PACKET
+#endif
+#ifdef AF_NETLINK
                        | AF_NETLINK
+#endif
                        /* | AF_DECnet */
                        /* | AF_IPX */
                        ) <= 127 ? 1 : -1];
@@ -346,6 +398,7 @@ typedef struct len_and_sockaddr {
        } u;
 } len_and_sockaddr;
 enum {
+       LSA_LEN_SIZE = offsetof(len_and_sockaddr, u),
        LSA_SIZEOF_SA = sizeof(
                union {
                        struct sockaddr sa;
@@ -361,7 +414,12 @@ enum {
  * af == AF_UNSPEC will result in trying to create IPv6 socket,
  * and if kernel doesn't support it, IPv4.
  */
-int xsocket_type(len_and_sockaddr **lsap, USE_FEATURE_IPV6(int af,) int sock_type);
+#if ENABLE_FEATURE_IPV6
+int xsocket_type(len_and_sockaddr **lsap, int af, int sock_type);
+#else
+int xsocket_type(len_and_sockaddr **lsap, int sock_type);
+#define xsocket_type(lsap, af, sock_type) xsocket_type((lsap), (sock_type))
+#endif
 int xsocket_stream(len_and_sockaddr **lsap);
 /* Create server socket bound to bindaddr:port. bindaddr can be NULL,
  * numeric IP ("N.N.N.N") or numeric IPv6 address,
@@ -386,14 +444,13 @@ len_and_sockaddr* host2sockaddr(const char *host, int port);
 /* Version which dies on error */
 len_and_sockaddr* xhost2sockaddr(const char *host, int port);
 len_and_sockaddr* xdotted2sockaddr(const char *host, int port);
-#if ENABLE_FEATURE_IPV6
 /* Same, useful if you want to force family (e.g. IPv6) */
+#if !ENABLE_FEATURE_IPV6
+#define host_and_af2sockaddr(host, port, af) host2sockaddr((host), (port))
+#define xhost_and_af2sockaddr(host, port, af) xhost2sockaddr((host), (port))
+#else
 len_and_sockaddr* host_and_af2sockaddr(const char *host, int port, sa_family_t af);
 len_and_sockaddr* xhost_and_af2sockaddr(const char *host, int port, sa_family_t af);
-#else
-/* [we evaluate af: think about "host_and_af2sockaddr(..., af++)"] */
-#define host_and_af2sockaddr(host, port, af) ((void)(af), host2sockaddr((host), (port)))
-#define xhost_and_af2sockaddr(host, port, af) ((void)(af), xhost2sockaddr((host), (port)))
 #endif
 /* Assign sin[6]_port member if the socket is an AF_INET[6] one,
  * otherwise no-op. Useful for ftp.
@@ -457,6 +514,9 @@ extern void *xzalloc(size_t size);
 extern void *xrealloc(void *old, size_t size);
 
 extern ssize_t safe_read(int fd, void *buf, size_t count);
+extern ssize_t nonblock_safe_read(int fd, void *buf, size_t count);
+// NB: will return short read on error, not -1,
+// if some data was read before error occurred
 extern ssize_t full_read(int fd, void *buf, size_t count);
 extern void xread(int fd, void *buf, size_t count);
 extern unsigned char xread_char(int fd);
@@ -464,12 +524,15 @@ extern unsigned char xread_char(int fd);
 extern char *reads(int fd, char *buf, size_t count);
 // Read one line a-la fgets. Reads byte-by-byte.
 // Useful when it is important to not read ahead.
+// Bytes are appended to pfx (which must be malloced, or NULL).
 extern char *xmalloc_reads(int fd, char *pfx);
 extern ssize_t read_close(int fd, void *buf, size_t count);
 extern ssize_t open_read_close(const char *filename, void *buf, size_t count);
 extern void *xmalloc_open_read_close(const char *filename, size_t *sizep);
 
 extern ssize_t safe_write(int fd, const void *buf, size_t count);
+// NB: will return short write on error, not -1,
+// if some data was written before error occurred
 extern ssize_t full_write(int fd, const void *buf, size_t count);
 extern void xwrite(int fd, const void *buf, size_t count);
 
@@ -495,12 +558,17 @@ extern FILE *fopen_or_warn(const char *filename, const char *mode);
 /* "Opens" stdin if filename is special, else just opens file: */
 extern FILE *fopen_or_warn_stdin(const char *filename);
 
+int bb_pstrcmp(const void *a, const void *b);
+void qsort_string_vector(char **sv, unsigned count);
+
 /* Wrapper which restarts poll on EINTR or ENOMEM.
  * On other errors complains [perror("poll")] and returns.
  * Warning! May take (much) longer than timeout_ms to return!
  * If this is a problem, use bare poll and open-code EINTR/ENOMEM handling */
 int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout_ms);
 
+char *safe_gethostname(void);
+
 /* Convert each alpha char in str to lower-case */
 char* str_tolower(char *str);
 
@@ -588,14 +656,14 @@ int bb_execvp(const char *file, char *const argv[]);
 pid_t spawn(char **argv);
 pid_t xspawn(char **argv);
 
-/* Unlike waitpid, waits ONLY for one process,
+int safe_waitpid(int pid, int *wstat, int options);
+/* Unlike waitpid, waits ONLY for one process.
  * It's safe to pass negative 'pids' from failed [v]fork -
  * wait4pid will return -1 (and will not clobber [v]fork's errno).
  * IOW: rc = wait4pid(spawn(argv));
  *      if (rc < 0) bb_perror_msg("%s", argv[0]);
  *      if (rc > 0) bb_error_msg("exit code: %d", rc);
  */
-int safe_waitpid(int pid, int *wstat, int options);
 int wait4pid(int pid);
 int wait_any_nohang(int *wstat);
 #define wait_crashed(w) ((w) & 127)
@@ -657,14 +725,17 @@ enum {
   void re_exec(char **argv) ATTRIBUTE_NORETURN;
   void forkexit_or_rexec(char **argv);
   extern bool re_execed;
+  int  BUG_fork_is_unavailable_on_nommu(void);
+  int  BUG_daemon_is_unavailable_on_nommu(void);
+  void BUG_bb_daemonize_is_unavailable_on_nommu(void);
 # define fork()          BUG_fork_is_unavailable_on_nommu()
 # define daemon(a,b)     BUG_daemon_is_unavailable_on_nommu()
 # define bb_daemonize(a) BUG_bb_daemonize_is_unavailable_on_nommu()
 #endif
 void bb_daemonize_or_rexec(int flags, char **argv);
 void bb_sanitize_stdio(void);
-/* Clear dangerous stuff, set PATH */
-void sanitize_env_for_suid(void);
+/* Clear dangerous stuff, set PATH. Return 1 if was run by different user. */
+int sanitize_env_if_suid(void);
 
 
 extern const char *opt_complementary;
@@ -807,8 +878,10 @@ extern void run_applet_and_exit(const char *name, char **argv);
 extern void run_applet_no_and_exit(int a, char **argv) ATTRIBUTE_NORETURN;
 #endif
 
+#ifdef HAVE_MNTENT_H
 extern int match_fstype(const struct mntent *mt, const char *fstypes);
 extern struct mntent *find_mount_point(const char *name, const char *table);
+#endif
 extern void erase_mtab(const char * name);
 extern unsigned int tty_baud_to_value(speed_t speed);
 extern speed_t tty_value_to_baud(unsigned int value);
@@ -852,7 +925,6 @@ char *bb_simplify_path(const char *path);
 #define FAIL_DELAY 3
 extern void bb_do_delay(int seconds);
 extern void change_identity(const struct passwd *pw);
-extern const char *change_identity_e2str(const struct passwd *pw);
 extern void run_shell(const char *shell, int loginshell, const char *command, const char **additional_args) ATTRIBUTE_NORETURN;
 extern void run_shell(const char *shell, int loginshell, const char *command, const char **additional_args);
 #if ENABLE_SELINUX
@@ -869,20 +941,20 @@ extern void selinux_or_die(void);
 extern int restricted_shell(const char *shell);
 
 /* setup_environment:
- * if loginshell = 1: cd(pw->pw_dir), clear environment, then set
+ * if clear_env = 1: cd(pw->pw_dir), clear environment, then set
  *   TERM=(old value)
  *   USER=pw->pw_name, LOGNAME=pw->pw_name
  *   PATH=bb_default_[root_]path
  *   HOME=pw->pw_dir
  *   SHELL=shell
- * else if changeenv = 1:
+ * else if change_env = 1:
  *   if not root (if pw->pw_uid != 0):
  *     USER=pw->pw_name, LOGNAME=pw->pw_name
  *   HOME=pw->pw_dir
  *   SHELL=shell
  * else does nothing
  */
-extern void setup_environment(const char *shell, int loginshell, int changeenv, const struct passwd *pw);
+extern void setup_environment(const char *shell, int clear_env, int change_env, const struct passwd *pw);
 extern int correct_password(const struct passwd *pw);
 /* Returns a ptr to static storage */
 extern char *pw_encrypt(const char *clear, const char *salt);
@@ -1048,7 +1120,7 @@ enum {
                        | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_START_TIME
                        | PSSCAN_TTY,
 };
-procps_status_t* alloc_procps_scan(int flags);
+//procps_status_t* alloc_procps_scan(void);
 void free_procps_scan(procps_status_t* sp);
 procps_status_t* procps_scan(procps_status_t* sp, int flags);
 /* Format cmdline (up to col chars) into char buf[col+1] */
@@ -1151,10 +1223,14 @@ extern char bb_common_bufsiz1[COMMON_BUFSIZE];
 struct globals;
 /* '*const' ptr makes gcc optimize code much better.
  * Magic prevents ptr_to_globals from going into rodata.
- * If you want to assign a value, use PTR_TO_GLOBALS = xxx */
+ * If you want to assign a value, use SET_PTR_TO_GLOBALS(x) */
 extern struct globals *const ptr_to_globals;
-#define PTR_TO_GLOBALS (*(struct globals**)&ptr_to_globals)
-
+/* At least gcc 3.4.6 on mipsel system needs optimization barrier */
+#define barrier() asm volatile("":::"memory")
+#define SET_PTR_TO_GLOBALS(x) do { \
+       (*(struct globals**)&ptr_to_globals) = (x); \
+       barrier(); \
+} while (0)
 
 /* You can change LIBBB_DEFAULT_LOGIN_SHELL, but don't use it,
  * use bb_default_login_shell and following defines.