summaryrefslogtreecommitdiff
path: root/lib/xwrap.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/xwrap.c')
-rw-r--r--lib/xwrap.c106
1 files changed, 77 insertions, 29 deletions
diff --git a/lib/xwrap.c b/lib/xwrap.c
index 6216d91..54f2cbb 100644
--- a/lib/xwrap.c
+++ b/lib/xwrap.c
@@ -9,15 +9,29 @@
#include "toys.h"
-// Strcpy with size checking: exit if there's not enough space for the string.
+// strcpy and strncat with size checking. Size is the total space in "dest",
+// including null terminator. Exit if there's not enough space for the string
+// (including space for the null terminator), because silently truncating is
+// still broken behavior. (And leaving the string unterminated is INSANE.)
void xstrncpy(char *dest, char *src, size_t size)
{
if (strlen(src)+1 > size) error_exit("'%s' > %ld bytes", src, (long)size);
strcpy(dest, src);
}
+void xstrncat(char *dest, char *src, size_t size)
+{
+ long len = strlen(src);
+
+ if (len+strlen(dest)+1 > size)
+ error_exit("'%s%s' > %ld bytes", dest, src, (long)size);
+ strcpy(dest+len, src);
+}
+
void xexit(void)
{
+ if (fflush(NULL) || ferror(stdout))
+ if (!toys.exitval) perror_msg("write");
if (toys.rebound) longjmp(*toys.rebound, 1);
else exit(toys.exitval);
}
@@ -52,9 +66,10 @@ void *xrealloc(void *ptr, size_t size)
// Die unless we can allocate a copy of this many bytes of string.
char *xstrndup(char *s, size_t n)
{
- char *ret = xmalloc(++n);
- strncpy(ret, s, n);
- ret[--n]=0;
+ char *ret = strndup(s, ++n);
+
+ if (!ret) error_exit("xstrndup");
+ ret[--n] = 0;
return ret;
}
@@ -114,26 +129,6 @@ void xflush(void)
if (fflush(stdout) || ferror(stdout)) perror_exit("write");;
}
-pid_t xfork(void)
-{
- pid_t pid = fork();
-
- if (pid < 0) perror_exit("fork");
-
- return pid;
-}
-
-// Call xexec with a chunk of optargs, starting at skip. (You can't just
-// call xexec() directly because toy_init() frees optargs.)
-void xexec_optargs(int skip)
-{
- char **s = toys.optargs;
-
- toys.optargs = 0;
- xexec(s+skip);
-}
-
-
// Die unless we can exec argv[] (or run builtin command). Note that anything
// with a path isn't a builtin, so /bin/sh won't match the builtin sh.
void xexec(char **argv)
@@ -343,7 +338,7 @@ void xstat(char *path, struct stat *st)
// Cannonicalize path, even to file with one or more missing components at end.
// if exact, require last path component to exist
-char *xabspath(char *path, int exact)
+char *xabspath(char *path, int exact)
{
struct string_list *todo, *done = 0;
int try = 9999, dirfd = open("/", 0);;
@@ -482,6 +477,38 @@ struct group *xgetgrgid(gid_t gid)
return group;
}
+struct passwd *xgetpwnamid(char *user)
+{
+ struct passwd *up = getpwnam(user);
+ uid_t uid;
+
+ if (!up) {
+ char *s = 0;
+
+ uid = estrtol(user, &s, 10);
+ if (!errno && s && !*s) up = getpwuid(uid);
+ }
+ if (!up) perror_exit("user '%s'", user);
+
+ return up;
+}
+
+struct group *xgetgrnamid(char *group)
+{
+ struct group *gr = getgrnam(group);
+ gid_t gid;
+
+ if (!gr) {
+ char *s = 0;
+
+ gid = estrtol(group, &s, 10);
+ if (!errno && s && !*s) gr = getgrgid(gid);
+ }
+ if (!gr) perror_exit("group '%s'", group);
+
+ return gr;
+}
+
struct passwd *xgetpwnam(char *name)
{
struct passwd *up = getpwnam(name);
@@ -587,13 +614,12 @@ void xpidfile(char *name)
void xsendfile(int in, int out)
{
long len;
- char buf[4096];
if (in<0) return;
for (;;) {
- len = xread(in, buf, 4096);
+ len = xread(in, libbuf, sizeof(libbuf));
if (len<1) break;
- xwrite(out, buf, len);
+ xwrite(out, libbuf, len);
}
}
@@ -605,7 +631,7 @@ long xparsetime(char *arg, long units, long *fraction)
if (CFG_TOYBOX_FLOAT) d = strtod(arg, &arg);
else l = strtoul(arg, &arg, 10);
-
+
// Parse suffix
if (*arg) {
int ismhd[]={1,60,3600,86400}, i = stridx("smhd", *arg);
@@ -633,3 +659,25 @@ void xregcomp(regex_t *preg, char *regex, int cflags)
error_exit("xregcomp: %s", libbuf);
}
}
+
+char *xtzset(char *new)
+{
+ char *tz = getenv("TZ");
+
+ if (tz) tz = xstrdup(tz);
+ if (setenv("TZ", new, 1)) perror_exit("setenv");
+ tzset();
+
+ return tz;
+}
+
+// Set a signal handler
+void xsignal(int signal, void *handler)
+{
+ struct sigaction *sa = (void *)libbuf;
+
+ memset(sa, 0, sizeof(struct sigaction));
+ sa->sa_handler = handler;
+
+ if (sigaction(signal, sa, 0)) perror_exit("xsignal %d", signal);
+}