blob: dd7c6c52729560610e3569c86f321662fa3b345e [file] [log] [blame]
landleycd9dfc32006-10-18 18:38:16 -04001/* vi: set sw=4 ts=4 :*/
landley4f344e32006-10-05 16:18:03 -04002/* functions.c - reusable stuff.
3 *
landleycd9dfc32006-10-18 18:38:16 -04004 * Functions with the x prefix are wrappers for library functions. They either
5 * succeed or kill the program with an error message, but never return failure.
6 * They usually have the same arguments and return value as the function they
7 * wrap.
landley4f344e32006-10-05 16:18:03 -04008 */
9
10#include "toys.h"
11
12// Die with an error message.
13void error_exit(char *msg, ...)
14{
15 va_list args;
16
17 va_start(args, msg);
18 fprintf(stderr, "%s: ", toys.which->name);
19 vfprintf(stderr, msg, args);
20 va_end(args);
21 exit(toys.exitval);
22}
23
landleycd9dfc32006-10-18 18:38:16 -040024// Like strncpy but always null terminated.
landley4f344e32006-10-05 16:18:03 -040025void strlcpy(char *dest, char *src, size_t size)
26{
27 strncpy(dest,src,size);
28 dest[size-1] = 0;
29}
30
31// Die unless we can allocate memory.
32void *xmalloc(size_t size)
33{
34 void *ret = malloc(size);
35 if (!ret) error_exit("xmalloc");
landleycd9dfc32006-10-18 18:38:16 -040036
37 return ret;
landley4f344e32006-10-05 16:18:03 -040038}
39
landleycd9dfc32006-10-18 18:38:16 -040040// Die unless we can allocate prezeroed memory.
41void *xzalloc(size_t size)
42{
43 void *ret = xmalloc(size);
44 bzero(ret,size);
45 return ret;
46}
47
48// Die unless we can change the size of an existing allocation, possibly
49// moving it. (Notice different arguments from libc function.)
50void xrealloc(void **ptr, size_t size)
51{
52 *ptr = realloc(*ptr, size);
53 if (!*ptr) error_exit("xrealloc");
54}
55
56// Die unless we can allocate a copy of this string.
landley4f344e32006-10-05 16:18:03 -040057void *xstrndup(char *s, size_t n)
58{
59 void *ret = xmalloc(++n);
60 strlcpy(ret, s, n);
61
62 return ret;
63}
64
landleycd9dfc32006-10-18 18:38:16 -040065// Die unless we can exec argv[] (or run builtin command). Note that anything
66// with a path isn't a builtin, so /bin/sh won't match the builtin sh.
landley4f344e32006-10-05 16:18:03 -040067void *xexec(char **argv)
68{
landleycd9dfc32006-10-18 18:38:16 -040069 toy_exec(argv);
landley4f344e32006-10-05 16:18:03 -040070 execvp(argv[0], argv);
71 error_exit("No %s", argv[0]);
72}
73
74// Die unless we can open/create a file, returning file descriptor.
75int xopen(char *path, int flags, int mode)
76{
77 int fd = open(path, flags, mode);
78 if (fd == -1) error_exit("No file %s\n", path);
79 return fd;
80}
81
82// Die unless we can open/create a file, returning FILE *.
83FILE *xfopen(char *path, char *mode)
84{
85 FILE *f = fopen(path, mode);
86 if (!f) error_exit("No file %s\n", path);
87 return f;
88}