blob: 2cfafb01a565960f405ad69673aadef8029d8acf [file] [log] [blame]
Eric Andersenaad1a882001-03-16 22:47:14 +00001/* vi: set sw=4 ts=4: */
2/*
3 * Utility routines.
4 *
Eric Andersenc7bda1c2004-03-15 08:29:22 +00005 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
Eric Andersenaad1a882001-03-16 22:47:14 +00006 *
Rob Landley4e9deec2006-02-20 02:44:30 +00007 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
Eric Andersenaad1a882001-03-16 22:47:14 +00008 */
9
Glenn L McGrath7ca04f32002-09-25 02:47:48 +000010#include <sys/types.h>
11#include <sys/stat.h>
Eric Andersenaad1a882001-03-16 22:47:14 +000012#include <stdio.h>
13#include <string.h>
14#include <stdlib.h>
15#include <unistd.h>
Glenn L McGrath7ca04f32002-09-25 02:47:48 +000016#include <fcntl.h>
Rob Landley552b56d2006-05-04 21:22:27 +000017#include "busybox.h"
Eric Andersenaad1a882001-03-16 22:47:14 +000018
19#ifndef DMALLOC
Manuel Novoa III cad53642003-03-19 09:13:01 +000020#ifdef L_xmalloc
Rob Landleydfba7412006-03-06 20:47:33 +000021void *xmalloc(size_t size)
Eric Andersenaad1a882001-03-16 22:47:14 +000022{
23 void *ptr = malloc(size);
Matt Kraaia99b1942002-02-26 15:28:22 +000024 if (ptr == NULL && size != 0)
Manuel Novoa III cad53642003-03-19 09:13:01 +000025 bb_error_msg_and_die(bb_msg_memory_exhausted);
Eric Andersenaad1a882001-03-16 22:47:14 +000026 return ptr;
27}
Manuel Novoa III cad53642003-03-19 09:13:01 +000028#endif
Eric Andersenaad1a882001-03-16 22:47:14 +000029
Manuel Novoa III cad53642003-03-19 09:13:01 +000030#ifdef L_xrealloc
Rob Landleydfba7412006-03-06 20:47:33 +000031void *xrealloc(void *ptr, size_t size)
Eric Andersenaad1a882001-03-16 22:47:14 +000032{
Matt Kraaia99b1942002-02-26 15:28:22 +000033 ptr = realloc(ptr, size);
34 if (ptr == NULL && size != 0)
Manuel Novoa III cad53642003-03-19 09:13:01 +000035 bb_error_msg_and_die(bb_msg_memory_exhausted);
Eric Andersenaad1a882001-03-16 22:47:14 +000036 return ptr;
37}
Manuel Novoa III cad53642003-03-19 09:13:01 +000038#endif
Eric Andersenaad1a882001-03-16 22:47:14 +000039
Rob Landley80b8ff02006-05-19 20:36:49 +000040#ifdef L_xzalloc
41void *xzalloc(size_t size)
42{
43 void *ptr = xmalloc(size);
44 memset(ptr, 0, size);
45 return ptr;
46}
47#endif
48
Manuel Novoa III cad53642003-03-19 09:13:01 +000049#ifdef L_xcalloc
Rob Landleydfba7412006-03-06 20:47:33 +000050void *xcalloc(size_t nmemb, size_t size)
Eric Andersenaad1a882001-03-16 22:47:14 +000051{
52 void *ptr = calloc(nmemb, size);
Matt Kraaia99b1942002-02-26 15:28:22 +000053 if (ptr == NULL && nmemb != 0 && size != 0)
Manuel Novoa III cad53642003-03-19 09:13:01 +000054 bb_error_msg_and_die(bb_msg_memory_exhausted);
Eric Andersenaad1a882001-03-16 22:47:14 +000055 return ptr;
56}
Manuel Novoa III cad53642003-03-19 09:13:01 +000057#endif
Eric Andersen9f894f42003-07-05 22:15:43 +000058#endif /* DMALLOC */
Eric Andersenaad1a882001-03-16 22:47:14 +000059
Manuel Novoa III cad53642003-03-19 09:13:01 +000060#ifdef L_xstrdup
Rob Landley31642d72006-03-14 21:45:38 +000061char * bb_xstrdup (const char *s)
62{
Eric Andersenaad1a882001-03-16 22:47:14 +000063 char *t;
64
65 if (s == NULL)
66 return NULL;
67
68 t = strdup (s);
69
70 if (t == NULL)
Manuel Novoa III cad53642003-03-19 09:13:01 +000071 bb_error_msg_and_die(bb_msg_memory_exhausted);
Eric Andersenaad1a882001-03-16 22:47:14 +000072
73 return t;
74}
75#endif
76
Manuel Novoa III cad53642003-03-19 09:13:01 +000077#ifdef L_xstrndup
Rob Landley31642d72006-03-14 21:45:38 +000078char * bb_xstrndup (const char *s, int n)
79{
Eric Andersenaad1a882001-03-16 22:47:14 +000080 char *t;
81
82 if (s == NULL)
Manuel Novoa III cad53642003-03-19 09:13:01 +000083 bb_error_msg_and_die("bb_xstrndup bug");
Eric Andersenaad1a882001-03-16 22:47:14 +000084
85 t = xmalloc(++n);
Eric Andersenc7bda1c2004-03-15 08:29:22 +000086
Eric Andersenaad1a882001-03-16 22:47:14 +000087 return safe_strncpy(t,s,n);
88}
Manuel Novoa III cad53642003-03-19 09:13:01 +000089#endif
Eric Andersenaad1a882001-03-16 22:47:14 +000090
Manuel Novoa III cad53642003-03-19 09:13:01 +000091#ifdef L_xfopen
92FILE *bb_xfopen(const char *path, const char *mode)
Eric Andersenaad1a882001-03-16 22:47:14 +000093{
94 FILE *fp;
95 if ((fp = fopen(path, mode)) == NULL)
Manuel Novoa III cad53642003-03-19 09:13:01 +000096 bb_perror_msg_and_die("%s", path);
Eric Andersenaad1a882001-03-16 22:47:14 +000097 return fp;
98}
Manuel Novoa III cad53642003-03-19 09:13:01 +000099#endif
Eric Andersenaad1a882001-03-16 22:47:14 +0000100
Manuel Novoa III cad53642003-03-19 09:13:01 +0000101#ifdef L_xopen
Rob Landleydfba7412006-03-06 20:47:33 +0000102int bb_xopen(const char *pathname, int flags)
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000103{
Bernhard Reutner-Fischerc2cb0f32006-04-13 12:45:04 +0000104 return bb_xopen3(pathname, flags, 0777);
105}
106#endif
107
108#ifdef L_xopen3
109int bb_xopen3(const char *pathname, int flags, int mode)
110{
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000111 int ret;
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000112
Bernhard Reutner-Fischerc2cb0f32006-04-13 12:45:04 +0000113 ret = open(pathname, flags, mode);
114 if (ret < 0) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000115 bb_perror_msg_and_die("%s", pathname);
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000116 }
117 return ret;
118}
Manuel Novoa III cad53642003-03-19 09:13:01 +0000119#endif
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000120
Manuel Novoa III cad53642003-03-19 09:13:01 +0000121#ifdef L_xread
Rob Landleydfba7412006-03-06 20:47:33 +0000122ssize_t bb_xread(int fd, void *buf, size_t count)
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000123{
124 ssize_t size;
125
126 size = read(fd, buf, count);
Bernhard Reutner-Fischerc2cb0f32006-04-13 12:45:04 +0000127 if (size < 0) {
"Vladimir N. Oleynik"4eb2fd62005-11-25 11:36:36 +0000128 bb_perror_msg_and_die(bb_msg_read_error);
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000129 }
130 return(size);
131}
Manuel Novoa III cad53642003-03-19 09:13:01 +0000132#endif
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000133
Manuel Novoa III cad53642003-03-19 09:13:01 +0000134#ifdef L_xread_all
Rob Landleydfba7412006-03-06 20:47:33 +0000135void bb_xread_all(int fd, void *buf, size_t count)
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000136{
137 ssize_t size;
138
Manuel Novoa III cad53642003-03-19 09:13:01 +0000139 while (count) {
140 if ((size = bb_xread(fd, buf, count)) == 0) { /* EOF */
141 bb_error_msg_and_die("Short read");
142 }
143 count -= size;
Manuel Novoa III 948d4902004-03-08 05:44:30 +0000144 buf = ((char *) buf) + size;
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000145 }
146 return;
147}
Manuel Novoa III cad53642003-03-19 09:13:01 +0000148#endif
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000149
Manuel Novoa III cad53642003-03-19 09:13:01 +0000150#ifdef L_xread_char
Rob Landleydfba7412006-03-06 20:47:33 +0000151unsigned char bb_xread_char(int fd)
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000152{
153 char tmp;
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000154
Manuel Novoa III cad53642003-03-19 09:13:01 +0000155 bb_xread_all(fd, &tmp, 1);
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000156
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000157 return(tmp);
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000158}
Manuel Novoa III cad53642003-03-19 09:13:01 +0000159#endif
Glenn L McGrath7ca04f32002-09-25 02:47:48 +0000160
Manuel Novoa III cad53642003-03-19 09:13:01 +0000161#ifdef L_xferror
Rob Landleydfba7412006-03-06 20:47:33 +0000162void bb_xferror(FILE *fp, const char *fn)
Manuel Novoa III cad53642003-03-19 09:13:01 +0000163{
164 if (ferror(fp)) {
165 bb_error_msg_and_die("%s", fn);
166 }
167}
168#endif
169
170#ifdef L_xferror_stdout
Rob Landleydfba7412006-03-06 20:47:33 +0000171void bb_xferror_stdout(void)
Manuel Novoa III cad53642003-03-19 09:13:01 +0000172{
173 bb_xferror(stdout, bb_msg_standard_output);
174}
175#endif
176
177#ifdef L_xfflush_stdout
Rob Landleydfba7412006-03-06 20:47:33 +0000178void bb_xfflush_stdout(void)
Manuel Novoa III cad53642003-03-19 09:13:01 +0000179{
180 if (fflush(stdout)) {
181 bb_perror_msg_and_die(bb_msg_standard_output);
182 }
183}
184#endif
Rob Landley399d2b52006-05-25 23:02:40 +0000185
186#ifdef L_spawn
187// This does a fork/exec in one call, using vfork().
188pid_t bb_spawn(char **argv)
189{
190 static int failed;
191 pid_t pid;
192
193 // Be nice to nommu machines.
194 failed = 0;
195 pid = vfork();
196 if (pid < 0) return pid;
197 if (!pid) {
198 execvp(*argv, argv);
199
200 // We're sharing a stack with blocked parent, let parent know we failed
201 // and then exit to unblock parent (but don't run atexit() stuff, which
202 // would screw up parent.)
203
204 failed = -1;
205 _exit(0);
206 }
207 return failed ? failed : pid;
208}
209#endif
210
211#ifdef L_xspawn
212pid_t bb_xspawn(char **argv)
213{
214 pid_t pid = bb_spawn(argv);
215 if (pid < 0) bb_perror_msg_and_die("%s", *argv);
216 return pid;
217}
218#endif