exec.c revision 236213
1/*
2 * FreeBSD install - a package for the installation and maintenance
3 * of non-core utilities.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * Jordan K. Hubbard
15 * 18 July 1993
16 *
17 * Miscellaneous system routines.
18 *
19 */
20
21#include <sys/cdefs.h>
22__FBSDID("$FreeBSD: head/usr.sbin/pkg_install/lib/exec.c 236213 2012-05-29 01:48:06Z kevlo $");
23
24#include "lib.h"
25#include <err.h>
26
27/*
28 * Unusual system() substitute.  Accepts format string and args,
29 * builds and executes command.  Returns exit code.
30 */
31
32int
33vsystem(const char *fmt, ...)
34{
35    va_list args;
36    char *cmd;
37    int ret, maxargs;
38
39    maxargs = sysconf(_SC_ARG_MAX);
40    maxargs -= 32;			/* some slop for the sh -c */
41    cmd = malloc(maxargs);
42    if (!cmd) {
43	warnx("vsystem can't alloc arg space");
44	return 1;
45    }
46
47    va_start(args, fmt);
48    if (vsnprintf(cmd, maxargs, fmt, args) > maxargs) {
49	warnx("vsystem args are too long");
50	va_end(args);
51	return 1;
52    }
53#ifdef DEBUG
54printf("Executing %s\n", cmd);
55#endif
56    ret = system(cmd);
57    va_end(args);
58    free(cmd);
59    return ret;
60}
61
62char *
63vpipe(const char *fmt, ...)
64{
65   FILE *fp;
66   char *cmd, *rp;
67   int maxargs;
68   va_list args;
69
70    rp = malloc(MAXPATHLEN);
71    if (!rp) {
72	warnx("vpipe can't alloc buffer space");
73	return NULL;
74    }
75    maxargs = sysconf(_SC_ARG_MAX);
76    maxargs -= 32;			    /* some slop for the sh -c */
77    cmd = alloca(maxargs);
78    if (!cmd) {
79	warnx("vpipe can't alloc arg space");
80	return NULL;
81    }
82
83    va_start(args, fmt);
84    if (vsnprintf(cmd, maxargs, fmt, args) > maxargs) {
85	warnx("vsystem args are too long");
86	va_end(args);
87	return NULL;
88    }
89#ifdef DEBUG
90    fprintf(stderr, "Executing %s\n", cmd);
91#endif
92    fflush(NULL);
93    fp = popen(cmd, "r");
94    if (fp == NULL) {
95	warnx("popen() failed");
96	return NULL;
97    }
98    get_string(rp, MAXPATHLEN, fp);
99#ifdef DEBUG
100    fprintf(stderr, "Returned %s\n", rp);
101#endif
102    va_end(args);
103    if (pclose(fp) || (strlen(rp) == 0)) {
104	free(rp);
105	return NULL;
106    }
107    return rp;
108}
109