return xopen3(pathname, flags, 0666);
}
+/* Die if we can't open an existing file readonly with O_NONBLOCK
+ * and return the fd.
+ * Note that for ioctl O_RDONLY is sufficient.
+ */
+int FAST_FUNC xopen_nonblocking(const char *pathname)
+{
+ return xopen(pathname, O_RDONLY | O_NONBLOCK);
+}
+
// Warn if we can't open a file and return a fd.
int FAST_FUNC open3_or_warn(const char *pathname, int flags, int mode)
{
bb_error_msg_and_die("short write");
}
}
+void FAST_FUNC xwrite_str(int fd, const char *str)
+{
+ xwrite(fd, str, strlen(str));
+}
+
+void FAST_FUNC xclose(int fd)
+{
+ if (close(fd))
+ bb_perror_msg_and_die("close failed");
+}
// Die with an error message if we can't lseek to the right spot.
off_t FAST_FUNC xlseek(int fd, off_t offset, int whence)
die_if_ferror(stdout, bb_msg_standard_output);
}
-// Die with an error message if we have trouble flushing stdout.
-void FAST_FUNC xfflush_stdout(void)
+int FAST_FUNC fflush_all(void)
{
- if (fflush(stdout)) {
- bb_perror_msg_and_die(bb_msg_standard_output);
- }
+ return fflush(NULL);
}
* then close that file. */
void FAST_FUNC xprint_and_close_file(FILE *file)
{
- fflush(stdout);
+ fflush_all();
// copyfd outputs error messages for us.
- if (bb_copyfd_eof(fileno(file), 1) == -1)
+ if (bb_copyfd_eof(fileno(file), STDOUT_FILENO) == -1)
xfunc_die();
fclose(file);
int r;
char *string_ptr;
-#if 1
- // GNU extension
va_start(p, format);
r = vasprintf(&string_ptr, format, p);
va_end(p);
-#else
- // Bloat for systems that haven't got the GNU extension.
- va_start(p, format);
- r = vsnprintf(NULL, 0, format, p);
- va_end(p);
- string_ptr = xmalloc(r+1);
- va_start(p, format);
- r = vsnprintf(string_ptr, r+1, format, p);
- va_end(p);
-#endif
if (r < 0)
bb_error_msg_and_die(bb_msg_memory_exhausted);
return string_ptr;
}
-#if 0 /* If we will ever meet a libc which hasn't [f]dprintf... */
-int FAST_FUNC fdprintf(int fd, const char *format, ...)
+void FAST_FUNC xsetenv(const char *key, const char *value)
{
- va_list p;
- int r;
- char *string_ptr;
+ if (setenv(key, value, 1))
+ bb_error_msg_and_die(bb_msg_memory_exhausted);
+}
-#if 1
- // GNU extension
- va_start(p, format);
- r = vasprintf(&string_ptr, format, p);
- va_end(p);
-#else
- // Bloat for systems that haven't got the GNU extension.
- va_start(p, format);
- r = vsnprintf(NULL, 0, format, p) + 1;
- va_end(p);
- string_ptr = malloc(r);
- if (string_ptr) {
- va_start(p, format);
- r = vsnprintf(string_ptr, r, format, p);
- va_end(p);
- }
-#endif
+/* Handles "VAR=VAL" strings, even those which are part of environ
+ * _right now_
+ */
+void FAST_FUNC bb_unsetenv(const char *var)
+{
+ char *tp = strchr(var, '=');
- if (r >= 0) {
- full_write(fd, string_ptr, r);
- free(string_ptr);
+ if (!tp) {
+ unsetenv(var);
+ return;
}
- return r;
-}
-#endif
-void FAST_FUNC xsetenv(const char *key, const char *value)
-{
- if (setenv(key, value, 1))
- bb_error_msg_and_die(bb_msg_memory_exhausted);
+ /* In case var was putenv'ed, we can't replace '='
+ * with NUL and unsetenv(var) - it won't work,
+ * env is modified by the replacement, unsetenv
+ * sees "VAR" instead of "VAR=VAL" and does not remove it!
+ * horror :( */
+ tp = xstrndup(var, tp - var);
+ unsetenv(tp);
+ free(tp);
}
+
// Die with an error message if we can't set gid. (Because resource limits may
// limit this user to a given number of processes, and if that fills up the
// setgid() will fail and we'll _still_be_root_, which is bad.)
const char *s = "INET";
if (domain == AF_PACKET) s = "PACKET";
if (domain == AF_NETLINK) s = "NETLINK";
-USE_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";)
+IF_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";)
bb_perror_msg_and_die("socket(AF_%s)", s);
#else
bb_perror_msg_and_die("socket");
/* Die with an error message if sendto failed.
* Return bytes sent otherwise */
-ssize_t FAST_FUNC xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
+ssize_t FAST_FUNC xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
socklen_t tolen)
{
ssize_t ret = sendto(s, buf, len, 0, to, tolen);