140 |
return xopen3(pathname, flags, 0666); |
return xopen3(pathname, flags, 0666); |
141 |
} |
} |
142 |
|
|
143 |
|
/* Die if we can't open an existing file readonly with O_NONBLOCK |
144 |
|
* and return the fd. |
145 |
|
* Note that for ioctl O_RDONLY is sufficient. |
146 |
|
*/ |
147 |
|
int FAST_FUNC xopen_nonblocking(const char *pathname) |
148 |
|
{ |
149 |
|
return xopen(pathname, O_RDONLY | O_NONBLOCK); |
150 |
|
} |
151 |
|
|
152 |
// Warn if we can't open a file and return a fd. |
// Warn if we can't open a file and return a fd. |
153 |
int FAST_FUNC open3_or_warn(const char *pathname, int flags, int mode) |
int FAST_FUNC open3_or_warn(const char *pathname, int flags, int mode) |
154 |
{ |
{ |
217 |
bb_error_msg_and_die("short write"); |
bb_error_msg_and_die("short write"); |
218 |
} |
} |
219 |
} |
} |
220 |
|
void FAST_FUNC xwrite_str(int fd, const char *str) |
221 |
|
{ |
222 |
|
xwrite(fd, str, strlen(str)); |
223 |
|
} |
224 |
|
|
225 |
|
void FAST_FUNC xclose(int fd) |
226 |
|
{ |
227 |
|
if (close(fd)) |
228 |
|
bb_perror_msg_and_die("close failed"); |
229 |
|
} |
230 |
|
|
231 |
// Die with an error message if we can't lseek to the right spot. |
// Die with an error message if we can't lseek to the right spot. |
232 |
off_t FAST_FUNC xlseek(int fd, off_t offset, int whence) |
off_t FAST_FUNC xlseek(int fd, off_t offset, int whence) |
255 |
die_if_ferror(stdout, bb_msg_standard_output); |
die_if_ferror(stdout, bb_msg_standard_output); |
256 |
} |
} |
257 |
|
|
258 |
// Die with an error message if we have trouble flushing stdout. |
int FAST_FUNC fflush_all(void) |
|
void FAST_FUNC xfflush_stdout(void) |
|
259 |
{ |
{ |
260 |
if (fflush(stdout)) { |
return fflush(NULL); |
|
bb_perror_msg_and_die(bb_msg_standard_output); |
|
|
} |
|
261 |
} |
} |
262 |
|
|
263 |
|
|
264 |
int FAST_FUNC bb_putchar(int ch) |
int FAST_FUNC bb_putchar(int ch) |
265 |
{ |
{ |
266 |
/* time.c needs putc(ch, stdout), not putchar(ch). |
return putchar(ch); |
|
* it does "stdout = stderr;", but then glibc's putchar() |
|
|
* doesn't work as expected. bad glibc, bad */ |
|
|
return putc(ch, stdout); |
|
267 |
} |
} |
268 |
|
|
269 |
/* Die with an error message if we can't copy an entire FILE* to stdout, |
/* Die with an error message if we can't copy an entire FILE* to stdout, |
270 |
* then close that file. */ |
* then close that file. */ |
271 |
void FAST_FUNC xprint_and_close_file(FILE *file) |
void FAST_FUNC xprint_and_close_file(FILE *file) |
272 |
{ |
{ |
273 |
fflush(stdout); |
fflush_all(); |
274 |
// copyfd outputs error messages for us. |
// copyfd outputs error messages for us. |
275 |
if (bb_copyfd_eof(fileno(file), 1) == -1) |
if (bb_copyfd_eof(fileno(file), STDOUT_FILENO) == -1) |
276 |
xfunc_die(); |
xfunc_die(); |
277 |
|
|
278 |
fclose(file); |
fclose(file); |
286 |
int r; |
int r; |
287 |
char *string_ptr; |
char *string_ptr; |
288 |
|
|
|
#if 1 |
|
|
// GNU extension |
|
289 |
va_start(p, format); |
va_start(p, format); |
290 |
r = vasprintf(&string_ptr, format, p); |
r = vasprintf(&string_ptr, format, p); |
291 |
va_end(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 |
|
292 |
|
|
293 |
if (r < 0) |
if (r < 0) |
294 |
bb_error_msg_and_die(bb_msg_memory_exhausted); |
bb_error_msg_and_die(bb_msg_memory_exhausted); |
295 |
return string_ptr; |
return string_ptr; |
296 |
} |
} |
297 |
|
|
298 |
#if 0 /* If we will ever meet a libc which hasn't [f]dprintf... */ |
void FAST_FUNC xsetenv(const char *key, const char *value) |
|
int FAST_FUNC fdprintf(int fd, const char *format, ...) |
|
299 |
{ |
{ |
300 |
va_list p; |
if (setenv(key, value, 1)) |
301 |
int r; |
bb_error_msg_and_die(bb_msg_memory_exhausted); |
302 |
char *string_ptr; |
} |
303 |
|
|
304 |
#if 1 |
/* Handles "VAR=VAL" strings, even those which are part of environ |
305 |
// GNU extension |
* _right now_ |
306 |
va_start(p, format); |
*/ |
307 |
r = vasprintf(&string_ptr, format, p); |
void FAST_FUNC bb_unsetenv(const char *var) |
308 |
va_end(p); |
{ |
309 |
#else |
char *tp = strchr(var, '='); |
|
// 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 |
|
310 |
|
|
311 |
if (r >= 0) { |
if (!tp) { |
312 |
full_write(fd, string_ptr, r); |
unsetenv(var); |
313 |
free(string_ptr); |
return; |
314 |
} |
} |
|
return r; |
|
|
} |
|
|
#endif |
|
315 |
|
|
316 |
void FAST_FUNC xsetenv(const char *key, const char *value) |
/* In case var was putenv'ed, we can't replace '=' |
317 |
{ |
* with NUL and unsetenv(var) - it won't work, |
318 |
if (setenv(key, value, 1)) |
* env is modified by the replacement, unsetenv |
319 |
bb_error_msg_and_die(bb_msg_memory_exhausted); |
* sees "VAR" instead of "VAR=VAL" and does not remove it! |
320 |
|
* horror :( */ |
321 |
|
tp = xstrndup(var, tp - var); |
322 |
|
unsetenv(tp); |
323 |
|
free(tp); |
324 |
} |
} |
325 |
|
|
326 |
|
|
327 |
// Die with an error message if we can't set gid. (Because resource limits may |
// Die with an error message if we can't set gid. (Because resource limits may |
328 |
// limit this user to a given number of processes, and if that fills up the |
// limit this user to a given number of processes, and if that fills up the |
329 |
// setgid() will fail and we'll _still_be_root_, which is bad.) |
// setgid() will fail and we'll _still_be_root_, which is bad.) |
384 |
const char *s = "INET"; |
const char *s = "INET"; |
385 |
if (domain == AF_PACKET) s = "PACKET"; |
if (domain == AF_PACKET) s = "PACKET"; |
386 |
if (domain == AF_NETLINK) s = "NETLINK"; |
if (domain == AF_NETLINK) s = "NETLINK"; |
387 |
USE_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";) |
IF_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";) |
388 |
bb_perror_msg_and_die("socket(AF_%s)", s); |
bb_perror_msg_and_die("socket(AF_%s,%d,%d)", s, type, protocol); |
389 |
#else |
#else |
390 |
bb_perror_msg_and_die("socket"); |
bb_perror_msg_and_die("socket"); |
391 |
#endif |
#endif |
408 |
|
|
409 |
/* Die with an error message if sendto failed. |
/* Die with an error message if sendto failed. |
410 |
* Return bytes sent otherwise */ |
* Return bytes sent otherwise */ |
411 |
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, |
412 |
socklen_t tolen) |
socklen_t tolen) |
413 |
{ |
{ |
414 |
ssize_t ret = sendto(s, buf, len, 0, to, tolen); |
ssize_t ret = sendto(s, buf, len, 0, to, tolen); |