From 1ef14f4bf9de937ea97086c8f473d5d08c89a00c Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sun, 9 Oct 2011 21:29:26 +0200 Subject: [PATCH] includes: add xalloc.h to unify memory allocations The xalloc.h provides necessary error checking. Signed-off-by: Jim Warner Signed-off-by: Sami Kerola --- include/xalloc.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ pgrep.c | 44 ++++++++++++++++--------------------- pmap.c | 6 ++---- skill.c | 4 ++-- sysctl.c | 19 ++++++++-------- tload.c | 8 +++---- watch.c | 5 +++-- 7 files changed, 94 insertions(+), 48 deletions(-) create mode 100644 include/xalloc.h diff --git a/include/xalloc.h b/include/xalloc.h new file mode 100644 index 00000000..dca64254 --- /dev/null +++ b/include/xalloc.h @@ -0,0 +1,56 @@ +/* + * General memory allocation wrappers for malloc, realloc, calloc + * and strdup. + */ + +#ifndef PROCPS_NG_XALLOC_H +#define PROCPS_NG_XALLOC_H + +#include +#include + +#include "c.h" + +#ifndef XALLOC_EXIT_CODE +# define XALLOC_EXIT_CODE EXIT_FAILURE +#endif + +static inline __ul_alloc_size(1) +void *xmalloc(const size_t size) +{ + void *ret = malloc(size); + if (!ret && size) + err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size); + return ret; +} + +static inline __ul_alloc_size(2) +void *xrealloc(void *ptr, const size_t size) +{ + void *ret = realloc(ptr, size); + if (!ret && size) + err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size); + return ret; +} + +static inline __ul_calloc_size(1, 2) +void *xcalloc(const size_t nelems, const size_t size) +{ + void *ret = calloc(nelems, size); + if (!ret && size && nelems) + err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size); + return ret; +} + +static inline char *xstrdup(const char *str) +{ + char *ret; + if (!str) + return NULL; + ret = strdup(str); + if (!ret) + err(XALLOC_EXIT_CODE, "cannot duplicate string"); + return ret; +} + +#endif /* PROCPS_NG_XALLOC_H */ diff --git a/pgrep.c b/pgrep.c index 5fea54d8..c0d0e9a4 100644 --- a/pgrep.c +++ b/pgrep.c @@ -28,19 +28,21 @@ #include #include +// EXIT_SUCCESS is 0 +// EXIT_FAILURE is 1 +#define EXIT_USAGE 2 +#define EXIT_FATAL 3 +#define XALLOC_EXIT_CODE EXIT_FATAL + #include "c.h" #include "nls.h" +#include "xalloc.h" #include "proc/readproc.h" #include "proc/sig.h" #include "proc/devname.h" #include "proc/sysinfo.h" #include "proc/version.h" /* procps_version */ -// EXIT_SUCCESS is 0 -// EXIT_FAILURE is 1 -#define EXIT_USAGE 2 -#define EXIT_FATAL 3 - static int i_am_pkill = 0; static const char *progname = "pgrep"; @@ -114,7 +116,7 @@ static int __attribute__ ((__noreturn__)) usage(int opt) static union el *split_list (const char *restrict str, int (*convert)(const char *, union el *)) { - char *copy = strdup (str); + char *copy = xstrdup (str); char *ptr = copy; char *sep_pos; int i = 0; @@ -125,9 +127,7 @@ static union el *split_list (const char *restrict str, int (*convert)(const char if (i == size) { size = size * 5 / 4 + 4; // add 1 because slot zero is a count - list = realloc (list, 1 + size * sizeof *list); - if (list == NULL) - exit (EXIT_FATAL); + list = xrealloc (list, 1 + size * sizeof *list); } sep_pos = strchr (ptr, ','); if (sep_pos) @@ -238,7 +238,7 @@ static union el *read_pidfile(void) goto out; if(*endp && !isspace(*endp)) goto out; - list = malloc(2 * sizeof *list); + list = xmalloc(2 * sizeof *list); list[0].num = 1; list[1].num = pid; out: @@ -322,7 +322,7 @@ static int conv_num (const char *restrict name, union el *restrict e) static int conv_str (const char *restrict name, union el *restrict e) { - e->str = strdup (name); + e->str = xstrdup (name); return 1; } @@ -396,9 +396,7 @@ static PROCTAB *do_openproc (void) if (opt_euid && !opt_negate) { int num = opt_euid[0].num; int i = num; - uid_t *uids = malloc (num * sizeof (uid_t)); - if (uids == NULL) - exit (EXIT_FATAL); + uid_t *uids = xmalloc (num * sizeof (uid_t)); while (i-- > 0) { uids[i] = opt_euid[i+1].num; } @@ -419,13 +417,9 @@ static regex_t * do_regcomp (void) char errbuf[256]; int re_err; - preg = malloc (sizeof (regex_t)); - if (preg == NULL) - exit (EXIT_FATAL); + preg = xmalloc (sizeof (regex_t)); if (opt_exact) { - re = malloc (strlen (opt_pattern) + 5); - if (re == NULL) - exit (EXIT_FATAL); + re = xmalloc (strlen (opt_pattern) + 5); sprintf (re, "^(%s)$", opt_pattern); } else { re = opt_pattern; @@ -543,14 +537,12 @@ static union el * select_procs (int *num) } if (matches == size) { size = size * 5 / 4 + 4; - list = realloc(list, size * sizeof *list); - if (list == NULL) - exit (EXIT_FATAL); + list = xrealloc(list, size * sizeof *list); } if (opt_long) { char buff[5096]; // FIXME sprintf (buff, "%d %s", task.XXXID, cmd); - list[matches++].str = strdup (buff); + list[matches++].str = xstrdup (buff); } else { list[matches++].num = task.XXXID; } @@ -631,7 +623,7 @@ static void parse_opts (int argc, char **argv) // case 'D': // FreeBSD: print info about non-matches for debugging // break; case 'F': // FreeBSD: the arg is a file containing a PID to match - opt_pidfile = strdup (optarg); + opt_pidfile = xstrdup (optarg); ++criteria_count; break; case 'G': // Solaris: match rgid/rgroup @@ -676,7 +668,7 @@ static void parse_opts (int argc, char **argv) opt_count = 1; break; case 'd': // Solaris: change the delimiter - opt_delim = strdup (optarg); + opt_delim = xstrdup (optarg); break; case 'f': // Solaris: match full process name (as in "ps -f") opt_full = 1; diff --git a/pmap.c b/pmap.c index 2b610bfb..e8846672 100644 --- a/pmap.c +++ b/pmap.c @@ -26,6 +26,7 @@ #include "c.h" #include "nls.h" #include "proc/escape.h" +#include "xalloc.h" #include "proc/readproc.h" #include "proc/version.h" @@ -449,10 +450,7 @@ int main(int argc, char **argv) if (d_option && x_option) errx(EXIT_FAILURE, _("options -d and -x cannot coexist")); - pidlist = malloc(sizeof(unsigned) * argc); - if (pidlist == NULL) - err(EXIT_FAILURE, _("cannot allocate %zu bytes"), - sizeof(unsigned) * argc); + pidlist = xmalloc(sizeof(unsigned) * argc); while (*argv) { char *walk = *argv++; diff --git a/skill.c b/skill.c index 2b9c9f64..4fe91400 100644 --- a/skill.c +++ b/skill.c @@ -24,6 +24,7 @@ #include "c.h" #include "nls.h" +#include "xalloc.h" #include "proc/pwcache.h" #include "proc/sig.h" #include "proc/devname.h" @@ -39,8 +40,7 @@ static const char **cmds; static int *pids; #define ENLIST(thing,addme) do{ \ -if(!thing##s) thing##s = malloc(sizeof(*thing##s)*saved_argc); \ -if(!thing##s) fprintf(stderr,_("No memory.\n")),exit(2); \ +if(!thing##s) thing##s = xmalloc(sizeof(*thing##s)*saved_argc); \ thing##s[thing##_count++] = addme; \ }while(0) diff --git a/sysctl.c b/sysctl.c index 92a3df5f..08d5462c 100644 --- a/sysctl.c +++ b/sysctl.c @@ -37,6 +37,7 @@ #include "c.h" #include "nls.h" +#include "xalloc.h" #include "proc/procps.h" #include "proc/version.h" @@ -155,7 +156,7 @@ static int ReadSetting(const char *restrict const name) { } /* used to display the output */ - outname = strdup(name); + outname = xstrdup(name); slashdot(outname,'/','.'); /* change / to . */ if (pattern && !pattern_match(outname, pattern)){ @@ -164,13 +165,13 @@ static int ReadSetting(const char *restrict const name) { } /* used to open the file */ - tmpname = malloc(strlen(name)+strlen(PROC_PATH)+2); + tmpname = xmalloc(strlen(name)+strlen(PROC_PATH)+2); strcpy(tmpname, PROC_PATH); strcat(tmpname, name); slashdot(tmpname+strlen(PROC_PATH),'.','/'); /* change . to / */ /* used to display the output */ - outname = strdup(name); + outname = xstrdup(name); slashdot(outname,'/','.'); /* change / to . */ if (stat(tmpname, &ts) < 0) { @@ -285,7 +286,7 @@ static int DisplayAll(const char *restrict const path) { readdir(dp); // skip .. while (( de = readdir(dp) )) { char *restrict tmpdir; - tmpdir = (char *restrict)malloc(strlen(path)+strlen(de->d_name)+2); + tmpdir = (char *restrict)xmalloc(strlen(path)+strlen(de->d_name)+2); sprintf(tmpdir, "%s%s", path, de->d_name); rc2 = stat(tmpdir, &ts); if (rc2 != 0) { @@ -339,14 +340,14 @@ static int WriteSetting(const char *setting) { } /* used to open the file */ - tmpname = malloc(equals-name+1+strlen(PROC_PATH)); + tmpname = xmalloc(equals-name+1+strlen(PROC_PATH)); strcpy(tmpname, PROC_PATH); strncat(tmpname, name, (int)(equals-name)); tmpname[equals-name+strlen(PROC_PATH)] = 0; slashdot(tmpname+strlen(PROC_PATH),'.','/'); /* change . to / */ /* used to display the output */ - outname = malloc(equals-name+1); + outname = xmalloc(equals-name+1); strncpy(outname, name, (int)(equals-name)); outname[equals-name] = 0; slashdot(outname,'/','.'); /* change / to . */ @@ -544,9 +545,9 @@ static int PreloadSystem(void) { continue; if (ncfgs % nprealloc == 0) { - cfgs = realloc(cfgs, sizeof(struct pair*)*(ncfgs+nprealloc)); + cfgs = xrealloc(cfgs, sizeof(struct pair*)*(ncfgs+nprealloc)); } - cfgs[ncfgs] = malloc(sizeof(struct pair) + strlen(de->d_name)*2+2 + strlen(dirs[di])+1); + cfgs[ncfgs] = xmalloc(sizeof(struct pair) + strlen(de->d_name)*2+2 + strlen(dirs[di])+1); cfgs[ncfgs]->name = (char*)cfgs[ncfgs]+sizeof(struct pair); strcpy(cfgs[ncfgs]->name, de->d_name); cfgs[ncfgs]->value = (char*)cfgs[ncfgs]+sizeof(struct pair) + strlen(cfgs[ncfgs]->name)+1; @@ -660,7 +661,7 @@ int main(int argc, char *argv[]) IgnoreError = true; return PreloadSystem(); case 'r': - pattern = strdup(optarg); + pattern = xstrdup(optarg); break; case 'V': printf(PROCPS_NG_VERSION); diff --git a/tload.c b/tload.c index 72ac1a26..e1cfd46b 100644 --- a/tload.c +++ b/tload.c @@ -13,6 +13,7 @@ #include "proc/sysinfo.h" #include "c.h" #include "nls.h" +#include "xalloc.h" #include #include @@ -54,12 +55,9 @@ static void setsize(int i) } scr_size = nrows * ncols; if (screen == NULL) - screen = (char *)malloc(scr_size); + screen = (char *)xmalloc(scr_size); else - screen = (char *)realloc(screen, scr_size); - - if (screen == NULL) - err(EXIT_FAILURE, _("cannot allocate %zu bytes"), scr_size); + screen = (char *)xrealloc(screen, scr_size); memset(screen, ' ', scr_size - 1); *(screen + scr_size - 2) = '\0'; diff --git a/watch.c b/watch.c index fd3259ce..bc7c49c5 100644 --- a/watch.c +++ b/watch.c @@ -17,6 +17,7 @@ #include "config.h" #include "nls.h" #include "proc/procps.h" +#include "xalloc.h" #include #include #include @@ -366,13 +367,13 @@ int main(int argc, char *argv[]) /* save for later */ command_argv = &(argv[optind]); - command = strdup(argv[optind++]); + command = xstrdup(argv[optind++]); command_length = strlen(command); for (; optind < argc; optind++) { char *endp; int s = strlen(argv[optind]); /* space and \0 */ - command = realloc(command, command_length + s + 2); + command = xrealloc(command, command_length + s + 2); endp = command + command_length; *endp = ' '; memcpy(endp + 1, argv[optind], s); -- 2.40.0