* Copyright (C) 2006 Rob Landley
* Copyright (C) 2006 Denys Vlasenko
*
- * Licensed under GPL version 2, see file LICENSE in this tarball for details.
+ * Licensed under GPLv2, see file LICENSE in this source tree.
*/
/* We need to have separate xfuncs.c and xfuncs_printf.c because
#include "libbb.h"
/* Turn on nonblocking I/O on a fd */
-int FAST_FUNC ndelay_on(int fd)
+void FAST_FUNC ndelay_on(int fd)
{
- return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
+ int flags = fcntl(fd, F_GETFL);
+ if (flags & O_NONBLOCK)
+ return;
+ fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
-int FAST_FUNC ndelay_off(int fd)
+void FAST_FUNC ndelay_off(int fd)
{
- return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
+ int flags = fcntl(fd, F_GETFL);
+ if (!(flags & O_NONBLOCK))
+ return;
+ fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
}
-int FAST_FUNC close_on_exec_on(int fd)
+void FAST_FUNC close_on_exec_on(int fd)
{
- return fcntl(fd, F_SETFD, FD_CLOEXEC);
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
}
char* FAST_FUNC strncpy_IFNAMSIZ(char *dst, const char *src)
char *s = getenv(env_name);
if (s) {
value = atoi(s);
- /* If LINES/COLUMNS are set, pretent that there is
+ /* If LINES/COLUMNS are set, pretend that there is
* no error getting w/h, this prevents some ugly
* cursor tricks by our callers */
*err = 0;
{
return tcsetattr(STDIN_FILENO, TCSANOW, tp);
}
+
+pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options)
+{
+ pid_t r;
+
+ do
+ r = waitpid(pid, wstat, options);
+ while ((r == -1) && (errno == EINTR));
+ return r;
+}
+
+pid_t FAST_FUNC wait_any_nohang(int *wstat)
+{
+ return safe_waitpid(-1, wstat, WNOHANG);
+}
+
+// Wait for the specified child PID to exit, returning child's error return.
+int FAST_FUNC wait4pid(pid_t pid)
+{
+ int status;
+
+ if (pid <= 0) {
+ /*errno = ECHILD; -- wrong. */
+ /* we expect errno to be already set from failed [v]fork/exec */
+ return -1;
+ }
+ if (safe_waitpid(pid, &status, 0) == -1)
+ return -1;
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
+ if (WIFSIGNALED(status))
+ return WTERMSIG(status) + 0x180;
+ return 0;
+}