Changeset View
Changeset View
Standalone View
Standalone View
lib/libdpv/util.c
- This file was added.
Property | Old Value | New Value |
---|---|---|
svn:eol-style | null | native \ No newline at end of property |
svn:keywords | null | FreeBSD=%H \ No newline at end of property |
svn:mime-type | null | text/plain \ No newline at end of property |
/*- | |||||
* Copyright (c) 2013-2014 Devin Teske <dteske@FreeBSD.org> | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
*/ | |||||
#include <sys/cdefs.h> | |||||
__FBSDID("$FreeBSD$"); | |||||
#include <err.h> | |||||
#include <limits.h> | |||||
#include <spawn.h> | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <unistd.h> | |||||
#include "util.h" | |||||
extern char **environ; | |||||
static char cmdbuf[CMDBUFMAX] = ""; | |||||
static char shellcmd[PATH_MAX] = PATH_SHELL; | |||||
static char *shellcmd_argv[6] = { | |||||
ngie: This should be implied with BSS initialization. | |||||
Not Done Inline ActionsDiscussed with julian@ and we both think it helps to keep the initializer. dteske: Discussed with julian@ and we both think it helps to keep the initializer. | |||||
shellcmd, | |||||
__DECONST(char *, "-c"), | |||||
cmdbuf, | |||||
__DECONST(char *, "--"), | |||||
shellcmd, | |||||
NULL, | |||||
}; | |||||
/* | |||||
* Spawn a sh(1) command. Writes the resulting process ID to the pid_t pointed | |||||
* at by `pid'. Returns a file descriptor (int) suitable for writing data to | |||||
Not Done Inline ActionsPlease have jilles@/someone from security@ review this really quickly. I don't remember whether there's an alternative to doing this or not in libc, but this kind of concerns me because there are string quoting issues at least with cmd. ngie: Please have jilles@/someone from security@ review this really quickly.
I don't remember… | |||||
Not Done Inline ActionsSure, no harm in having him take a second look. dteske: Sure, no harm in having him take a second look. | |||||
* the spawned command (data written to file descriptor is seen as standard-in | |||||
* by the spawned sh(1) command). Returns `-1' if unable to spawn command. | |||||
* | |||||
* If cmd contains a single "%s" sequence, replace it with label if non-NULL. | |||||
*/ | |||||
int | |||||
shell_spawn_pipecmd(const char *cmd, const char *label, pid_t *pid) | |||||
{ | |||||
int error; | |||||
int len; | |||||
posix_spawn_file_actions_t action; | |||||
#if SHELL_SPAWN_DEBUG | |||||
unsigned int i; | |||||
#endif | |||||
int stdin_pipe[2] = { -1, -1 }; | |||||
/* Populate argument array */ | |||||
if (label != NULL && fmtcheck(cmd, "%s") == cmd) | |||||
len = snprintf(cmdbuf, CMDBUFMAX, cmd, label); | |||||
else | |||||
len = snprintf(cmdbuf, CMDBUFMAX, "%s", cmd); | |||||
if (len >= CMDBUFMAX) { | |||||
warnx("%s:%d:%s: cmdbuf[%u] too small to hold cmd argument", | |||||
__FILE__, __LINE__, __func__, CMDBUFMAX); | |||||
return (-1); | |||||
} | |||||
/* Open a pipe to communicate with [X]dialog(1) */ | |||||
if (pipe(stdin_pipe) < 0) | |||||
err(EXIT_FAILURE, "%s: pipe(2)", __func__); | |||||
/* Fork sh(1) process */ | |||||
#if SHELL_SPAWN_DEBUG | |||||
fprintf(stderr, "%s: spawning `", __func__); | |||||
for (i = 0; shellcmd_argv[i] != NULL; i++) { | |||||
if (i == 0) | |||||
fprintf(stderr, "%s", shellcmd_argv[i]); | |||||
else if (i == 2) | |||||
fprintf(stderr, " '%s'", shellcmd_argv[i]); | |||||
else | |||||
fprintf(stderr, " %s", shellcmd_argv[i]); | |||||
} | |||||
fprintf(stderr, "'\n"); | |||||
#endif | |||||
posix_spawn_file_actions_init(&action); | |||||
posix_spawn_file_actions_adddup2(&action, stdin_pipe[0], STDIN_FILENO); | |||||
posix_spawn_file_actions_addclose(&action, stdin_pipe[1]); | |||||
error = posix_spawnp(pid, shellcmd, &action, | |||||
(const posix_spawnattr_t *)NULL, shellcmd_argv, environ); | |||||
if (error != 0) | |||||
err(EXIT_FAILURE, "%s: posix_spawnp(3)", __func__); | |||||
return stdin_pipe[1]; | |||||
} | |||||
Not Done Inline ActionsMemory leaked intentionally? ngie: Memory leaked intentionally? | |||||
Not Done Inline ActionsYes, haven't found a way to prevent the segmentation fault that arises from attempting to free the positional argument array (even if waiting until after the spawned child process has closed). Minimal impact, but for good measure, I addressed in Diff #1397 additional memory management issues. dteske: Yes, haven't found a way to prevent the segmentation fault that arises from attempting to free… |
This should be implied with BSS initialization.