You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2010/01/11 07:51:29 UTC
svn commit: r897765 - in /commons/sandbox/runtime/trunk/src/main/native:
include/acr_args.h include/acr_string.h
include/arch/windows/acr_arch_private.h os/win32/exec.c port/shquote.c
shared/args.c shared/sbuf.c shared/string.c test/testsuite.c
Author: mturk
Date: Mon Jan 11 06:51:28 2010
New Revision: 897765
URL: http://svn.apache.org/viewvc?rev=897765&view=rev
Log:
Misc process argument fixes
Modified:
commons/sandbox/runtime/trunk/src/main/native/include/acr_args.h
commons/sandbox/runtime/trunk/src/main/native/include/acr_string.h
commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h
commons/sandbox/runtime/trunk/src/main/native/os/win32/exec.c
commons/sandbox/runtime/trunk/src/main/native/port/shquote.c
commons/sandbox/runtime/trunk/src/main/native/shared/args.c
commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c
commons/sandbox/runtime/trunk/src/main/native/shared/string.c
commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_args.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_args.h?rev=897765&r1=897764&r2=897765&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_args.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_args.h Mon Jan 11 06:51:28 2010
@@ -50,39 +50,12 @@
ACR_DECLARE(int) ACR_StringToArgvA(const char *cmdline,
char ***argv);
-#if defined(WIN32)
-/**
- * Unicode version of ACR_StringToArgvA
- */
-ACR_DECLARE(int) ACR_StringToArgvW(const wchar_t *cmdline,
- wchar_t ***argv);
-
-#endif
-
-/**
- * Duplicate argument array.
- * @param argv Argument array to duplicate. It has to be NULL terminated.
- * @return duplicated array.
- * @note Single free is needed to free the entire array data storage.
- * Like with ACR_StringToArgv function the argv[0] can be directly
- * used by functions that require zero separated double zero terminated
- * string.
- */
-ACR_DECLARE(char **) ACR_DuplicateArgsA(const char *const *argv);
-
-/**
- * Unicode version of ACR_DuplicateArgsA.
- * @note In addition to ACR_DuplicateArgsA, the unicode version double quotes
- * the first argument (argv[0]) if it contains space or tab characters.
- */
-ACR_DECLARE(wchar_t **) ACR_DuplicateArgsW(const wchar_t *const *argv);
-
/**
* Merge two argument arrays into one.
* @param argv1 Source argument array.
* @param argv2 Arrgument array to concat to the first one.
- * @note Any of the source argument array can be NULL in which
- * case function behaves like ACR_DuplicateArgs function.
+ * @note The second array can be NULL in which case the
+ * function duplicates first array.
*/
ACR_DECLARE(char **) ACR_MergeArgsA(const char *const *argv1,
const char *const *argv2);
@@ -93,9 +66,35 @@
ACR_DECLARE(wchar_t **) ACR_MergeArgsW(const wchar_t *const *argv1,
const wchar_t *const *argv2);
+/**
+ * Convert argument arrays into space separate string.
+ * @param argv Source argument array.
+ * @return Space separated argument. If argument is empty string
+ * it is concatenaed as "".
+ * Use x_free when allocated memory is no longer needed.
+ */
+ACR_DECLARE(char *) ACR_ArgsToStringA(const char *const *argv);
+
+/**
+ * Unicode version of ACR_ArgsToStringA.
+ */
+ACR_DECLARE(wchar_t *) ACR_ArgsToStringW(const wchar_t *const *argv);
+
+/**
+ * Sort the array of string using case insensitive order
+ * @param pointer to char array to sort.
+ */
+ACR_DECLARE(void) ACR_ArgsSortA(char *const **args);
+
+/**
+ * Sort the array of wide string using case insensitive order
+ * @param pointer to the wide char array to sort.
+ */
+ACR_DECLARE(void) ACR_ArgsSortW(wchar_t *const **args);
+
+
#ifdef __cplusplus
}
#endif
#endif /* _ACR_ARGS_H */
-
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_string.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_string.h?rev=897765&r1=897764&r2=897765&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_string.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_string.h Mon Jan 11 06:51:28 2010
@@ -147,6 +147,8 @@
*/
ACR_DECLARE(void) ACR_ReleaseMbString(JNIEnv *env, jbyteArray arr, char *s);
+ACR_DECLARE(wchar_t *) ACR_Utf8ToWcs(JNIEnv *env, const char *str);
+
/** Match ascii string to the pattern.
* Based loosely on sections of wildmat.c by Rich Salz
* @param str String to match.
@@ -413,7 +415,6 @@
/**
* Convert the multipart string to Java String array.
- * @param env Current JNI environment.
* @param str String to use.
* @return Java string array.
*/
@@ -421,23 +422,22 @@
/**
* Convert the multipart string to pointer array.
- * @param env Current JNI environment.
* @param str String to use.
* @return char array. Use ACR_Free when no longer needed.
* @note Returned array is always NULL terminated.
*/
-ACR_DECLARE(char **) ACR_MszStrToArrayA(JNIEnv *env,
- const char *str);
+ACR_DECLARE(char **) ACR_MszStrToArrayA(const char *str);
/**
* Convert the multipart string to pointer array.
- * @param env Current JNI environment.
* @param str String to use.
* @return wide char array. Use ACR_Free when no longer needed.
* @note Returned array is always NULL terminated.
*/
-ACR_DECLARE(wchar_t **) ACR_MszStrToArrayW(JNIEnv *env,
- const wchar_t *str);
+ACR_DECLARE(wchar_t **) ACR_MszStrToArrayW(const wchar_t *str);
+
+ACR_DECLARE(char *) ACR_ArrayToMszStrA(const char *const *arr);
+ACR_DECLARE(wchar_t *) ACR_ArrayToMszStrW(const wchar_t *const *arr);
/**
* Convert all tab characters in a string to single space character.
@@ -459,18 +459,6 @@
*/
ACR_DECLARE(wchar_t *) ACR_wcsqtab2ss(wchar_t *str);
-/**
- * Sort the array of string using case insensitive order
- * @param pointer to char array to sort.
- */
-ACR_DECLARE(void) ACR_StrArraySortA(char ***args);
-
-/**
- * Sort the array of wide string using case insensitive order
- * @param pointer to the wide char array to sort.
- */
-ACR_DECLARE(void) ACR_StrArraySortW(wchar_t ***args);
-
#ifdef __cplusplus
}
#endif
Modified: commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h?rev=897765&r1=897764&r2=897765&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h Mon Jan 11 06:51:28 2010
@@ -265,7 +265,8 @@
};
-typedef int rlim_t;
+#define RLIMIT_VMEM 1
+typedef size_t rlim_t;
struct rlimit {
rlim_t rlim_cur; /* Soft limit */
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/exec.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/exec.c?rev=897765&r1=897764&r2=897765&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/exec.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/exec.c Mon Jan 11 06:51:28 2010
@@ -135,6 +135,19 @@
}
}
+static int limit_proc(HANDLE hProc, acr_proc_limit_t *limit)
+{
+ if (limit->mem != NULL) {
+ if (!SetProcessWorkingSetSize(hProc,
+ limit->mem->rlim_cur,
+ limit->mem->rlim_max)) {
+ return ACR_GET_OS_ERROR();
+ }
+ }
+
+ return 0;
+}
+
typedef struct OVERLAPPED_BUFFER {
char buff[512];
DWORD stat;
@@ -142,7 +155,7 @@
} OVERLAPPED_BUFFER;
static int do_exec(acr_exec_t *ep, const wchar_t *cmdline,
- wchar_t **argv,
+ const wchar_t **argv,
wchar_t *const *envp)
{
PROCESS_INFORMATION pi;
@@ -161,28 +174,28 @@
DWORD dwPipeFlags;
const char *inpp = NULL;
wchar_t *args = NULL;
+ wchar_t *envb = NULL;
acr_time_t endat = 0;
BOOL iostat;
ep->exitwhy = ACR_PARENT_ERROR;
if (argv) {
- size_t argc;
- size_t argl;
-
- argc = ACR_MszStrSizeW(*argv, &argl);
- if (argc == (size_t)-1) {
- rc = ACR_EINVAL;
- goto cleanup;
- }
- argl += (argc * 2);
- args = x_malloc(argl * sizeof(wchar_t));
+ args = ACR_ArgsToStringW(argv);
if (!args) {
rc = ACR_ENOMEM;
goto cleanup;
}
- if (wcsquotev(argc, argv, args, argl) == (size_t)-1) {
- rc = ACR_EINVAL;
+ printf("CMD %S\n", cmdline);
+ printf("ARG %S\n", args);
+ }
+ if (envp) {
+ /* Environmet is supposed to be sorted
+ */
+ ACR_ArgsSortW(&envp);
+ envb = ACR_ArrayToMszStrW(envp);
+ if (!envb) {
+ rc = ACR_ENOMEM;
goto cleanup;
}
}
@@ -287,7 +300,7 @@
NULL, /* Proc & thread security attributes */
TRUE, /* Inherit handles */
dwCreationFlags, /* Creation flags */
- envp, /* Environment block */
+ envb, /* Environment block */
ep->currdir, /* Current directory name */
&si,
&pi);
@@ -305,7 +318,7 @@
NULL, /* Proc & thread security attributes */
TRUE, /* Inherit handles */
dwCreationFlags, /* Creation flags */
- envp, /* Environment block */
+ envb, /* Environment block */
ep->currdir, /* Current directory name */
&si,
&pi);
@@ -322,6 +335,13 @@
SAFE_CLOSE_HANDLE(pipes[PIPE_STDOUT_WRS]);
SAFE_CLOSE_HANDLE(pipes[PIPE_STDERR_WRS]);
+ if ((rc = limit_proc(pi.hProcess, &ep->limit))) {
+ /* Failed setting new process limits.
+ */
+ TerminateProcess(pi.hProcess, 9);
+ ep->exitwhy = ACR_CHILD_SIGNAL;
+ goto cleanup;
+ }
if (ep->flags & ACR_PROC_DETACHED) {
/* We are done in case of detached process
*/
@@ -528,6 +548,7 @@
SAFE_CLOSE_HANDLE(ob[i].o.hEvent);
}
x_free(args);
+ x_free(envb);
return ep->exitwhy;
}
@@ -536,7 +557,7 @@
{
int rc;
wchar_t **args = NULL;
- const wchar_t *sa[4] = { SHELL_PATH, L"/C", cmdline, NULL };
+ const wchar_t *sa[5] = { SHELL_PATH, L"/D", L"/C", cmdline, NULL };
if (!(args = ACR_MergeArgsW((const wchar_t *const *)sa, NULL))) {
ep->exitval = ACR_GET_OS_ERROR();
@@ -556,16 +577,17 @@
{
int rc;
wchar_t **args = NULL;
- const wchar_t *sa[5] = { SHELL_PATH, L"/C", L"call", fname, NULL };
+ const wchar_t *sa[5] = { SHELL_PATH, L"/D", L"/C", fname, NULL };
if (!(args = ACR_MergeArgsW((const wchar_t *const *)sa, argv))) {
ep->exitval = ACR_GET_OS_ERROR();
ep->exitwhy = ACR_PARENT_ERROR;
return ep->exitwhy;
}
+
rc = do_exec(ep, args[0], args, envp);
- x_free(args);
+ x_free(args);
return rc;
}
Modified: commons/sandbox/runtime/trunk/src/main/native/port/shquote.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/port/shquote.c?rev=897765&r1=897764&r2=897765&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/port/shquote.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/port/shquote.c Mon Jan 11 06:51:28 2010
@@ -162,33 +162,38 @@
rv = 0;
+ if (argc < 0) {
+ const char *const *ap = argv;
+ argc = 0;
+ if (ap) {
+ while (*ap) {
+ argc++;
+ ap++;
+ }
+ }
+ }
if (argc == 0) {
- if (bufsize != 0)
- *buf = '\0';
- return rv;
+ PUTC('\0');
+ return 0;
}
for (i = 0; i < argc; i++) {
+ if (i != 0) {
+ /* Add space before next arg */
+ PUTC(' ');
+ }
+
callrv = shquote(argv[i], buf, bufsize);
if (callrv == (size_t)-1)
- goto bad;
- rv += callrv;
- buf += callrv;
- bufsize = (bufsize > callrv) ? (bufsize - callrv) : 0;
-
- if (i < (argc - 1)) {
- rv++;
- if (bufsize > 1) {
- *buf++ = ' ';
- bufsize--;
- }
+ return callrv;
+ if (callrv) {
+ rv += callrv;
+ buf += callrv;
+ bufsize = (bufsize > callrv) ? (bufsize - callrv) : 0;
}
}
return rv;
-
-bad:
- return (size_t)-1;
}
#endif /* ACR_WANT_SHQUOTE */
@@ -197,49 +202,46 @@
*/
size_t strquote(const char *arg, char *buf, size_t bufsize)
{
- char c, lastc;
- size_t rv;
+ char c;
+ size_t rv = 0;
+ size_t quoted = 0;
int n;
- rv = 0;
- lastc = 0;
- if (!strpbrk(arg, " \t")) {
- /* Just copy over the arg */
- return strlcpy(buf, arg, bufsize);
+ /* Empty args are skipped */
+ if (!*arg) {
+ PUTC('\0');
+ return 0;
}
- if (*arg != '"') {
+ if (strpbrk(arg, " \t")) {
+ quoted = 1;
+ }
+ if (quoted) {
PUTC('"');
}
for (;;) {
INCH();
- if (n <= 0)
+ if (n == 0)
break;
- arg += n;
- lastc = c;
if (c == '"') {
- if (rv != 0) {
- PUTC('"');
- }
PUTC('\\');
- PUTC('"');
- for (;;) {
- INCH();
- if (n <= 0 || c != '"')
- break;
+ }
+ else if (c == '\\') {
+ const char *bsp = arg;
+ /* Add extra backslash for each backslash
+ * followed by double quoute.
+ */
+ while (*bsp && *bsp == '\\')
+ bsp++;
+ if (*bsp == '"') {
PUTC('\\');
- PUTC('"');
- arg += n;
}
- if (n > 0) {
- PUTC('"');
- }
- }
- else {
- PUTC(c);
+
}
+ PUTC(c);
+ arg++;
}
- if (lastc != '"') {
+ if (quoted) {
PUTC('"');
}
/* Put NUL terminator, but don't count the NUL. */
@@ -251,49 +253,46 @@
size_t wcsquote(const wchar_t *arg, wchar_t *buf, size_t bufsize)
{
- wchar_t c, lastc;
- size_t rv;
+ wchar_t c;
+ size_t rv = 0;
+ size_t quoted = 0;
int n;
- rv = 0;
- lastc = 0;
- if (!wcspbrk(arg, L" \t")) {
- /* Just copy over the arg */
- return wcslcpy(buf, arg, bufsize);
+ /* Empty args are skipped */
+ if (!*arg) {
+ PUTC(L'\0');
+ return 0;
}
- if (*arg != L'"') {
+ if (wcspbrk(arg, L" \t")) {
+ quoted = 1;
+ }
+ if (quoted) {
PUTC(L'"');
}
for (;;) {
INCH();
- if (n <= 0)
+ if (n == 0)
break;
- arg += n;
- lastc = c;
if (c == L'"') {
- if (rv != 0) {
- PUTC(L'"');
- }
PUTC(L'\\');
- PUTC(L'"');
- for (;;) {
- INCH();
- if (n <= 0 || c != L'"')
- break;
+ }
+ else if (c == L'\\') {
+ const wchar_t *bsp = arg;
+ /* Add extra backslash for each backslash
+ * followed by double quoute.
+ */
+ while (*bsp && *bsp == L'\\')
+ bsp++;
+ if (*bsp == L'"') {
PUTC(L'\\');
- PUTC(L'"');
- arg += n;
- }
- if (n > 0) {
- PUTC(L'"');
}
+
}
- else {
- PUTC(c);
- }
+ PUTC(c);
+ arg++;
}
- if (lastc != L'"') {
+ if (quoted) {
PUTC(L'"');
}
/* Put NUL terminator, but don't count the NUL. */
@@ -315,31 +314,36 @@
rv = 0;
+ if (argc < 0) {
+ const wchar_t *const *ap = argv;
+ argc = 0;
+ if (ap) {
+ while (*ap) {
+ argc++;
+ ap++;
+ }
+ }
+ }
+
if (argc == 0) {
- if (bufsize != 0)
- *buf = L'\0';
- return rv;
+ PUTC(L'\0');
+ return 0;
}
for (i = 0; i < argc; i++) {
+ if (i != 0) {
+ /* Add space before next arg */
+ PUTC(L' ');
+ }
callrv = wcsquote(argv[i], buf, bufsize);
if (callrv == (size_t)-1)
- goto bad;
- rv += callrv;
- buf += callrv;
- bufsize = (bufsize > callrv) ? (bufsize - callrv) : 0;
-
- if (i < (argc - 1)) {
- rv++;
- if (bufsize > 1) {
- *buf++ = L' ';
- bufsize--;
- }
+ return callrv;
+ if (callrv) {
+ rv += (callrv + 1);
+ buf += callrv;
+ bufsize = (bufsize > callrv) ? (bufsize - callrv) : 0;
}
}
return rv;
-
-bad:
- return (size_t)-1;
}
Modified: commons/sandbox/runtime/trunk/src/main/native/shared/args.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/args.c?rev=897765&r1=897764&r2=897765&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/args.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/args.c Mon Jan 11 06:51:28 2010
@@ -23,6 +23,8 @@
#include "acr_string.h"
#include "acr_sbuf.h"
#include "acr_env.h"
+#include "acr_port.h"
+#include "acr_args.h"
/**
* Just like strpbrk but it doesn't break if the char
@@ -279,302 +281,58 @@
return argnum;
}
-#if defined(WIN32)
-/* Wide char versions make sense on Windows only
- */
-static wchar_t *wcspbrk_s(const wchar_t *s1, const wchar_t *s2)
-{
- const wchar_t *scanp;
- int c, sc, pc = *s1;
-
- /* Some early sanity check */
- if (!s1 || !*s1)
- return NULL;
- while ((c = *s1++) != 0) {
- for (scanp = s2; (sc = *scanp++) != 0;) {
- if (sc == c && pc != L'\'')
- return (wchar_t *)(s1 - 1);
- }
- /* Don't update the previous marker if it was \' already
- * In that case we have escaped single quote.
- */
- if (pc == L'\\' && c == L'\'')
- pc = 0;
- else
- pc = c;
- }
- return NULL;
-}
-
-static wchar_t * _wcsexpand(wchar_t *str)
-{
- wchar_t *var_pos;
- wchar_t *var_end;
- wchar_t *var_ptr;
- wchar_t *var_rep;
- acr_wbuf_t sbuf;
-
- var_ptr = str;
-
- if (!var_ptr || !*var_ptr)
- return str; /* Guard against zero input */
- var_pos = wcspbrk_s(var_ptr, L"$");
- if (!var_pos) {
- wchar_t *buf;
- DWORD siz;
-
- siz = ExpandEnvironmentStringsW(str, NULL, 0);
- if (siz) {
- buf = s_malloc(wchar_t, siz);
- if (buf == NULL)
- return str;
- siz = ExpandEnvironmentStringsW(str, buf, siz);
- if (!siz) {
- x_free(buf);
- return str;
- }
- x_free(str);
- return buf;
- }
- return str;
- }
- acr_wbuf_new(&sbuf, NULL, wcslen(str), ACR_SBUF_AUTOEXTEND);
- /* Loop for each unescaped $ */
- while (var_pos) {
- int wch = 0;
- var_end = NULL;
- var_rep = NULL;
- if (*(var_pos + 1) == L'(') {
- var_end = wcspbrk(var_pos + 1, L" })");
- wch = L')';
- }
- else if (*(var_pos + 1) == L'{') {
- var_end = wcspbrk(var_pos + 1, L" })");
- wch = L'}';
- }
- if (var_end && *var_end == wch) {
- *var_pos++ = L'\0';
- *var_pos++ = L'\0';
- *var_end++ = L'\0';
- /* Add the string before $ */
- acr_wbuf_cat(&sbuf, var_ptr);
- /* var_pos holds the variable name */
- var_rep = acr_EnvGetW(var_pos);
- if (var_rep) {
- acr_wbuf_cat(&sbuf, var_rep);
- x_free(var_rep);
- }
- else {
- acr_wbuf_putc(&sbuf, L'$');
- if (wch == L'}')
- acr_wbuf_putc(&sbuf, L'{');
- else
- acr_wbuf_putc(&sbuf, L'(');
- acr_wbuf_cat(&sbuf, var_pos);
- acr_wbuf_putc(&sbuf, wch);
- }
- var_ptr = var_end;
- var_pos = wcspbrk_s(var_ptr, L"$");
- }
- else {
- *var_pos++ = L'\0';
- acr_wbuf_cat(&sbuf, var_ptr);
- acr_wbuf_putc(&sbuf, L'$');
- var_ptr = var_pos;
- var_pos = wcspbrk_s(var_ptr, L"$");
- }
- }
- /* Add what's left from the original string */
- acr_wbuf_cat(&sbuf, var_ptr);
- acr_wbuf_finish(&sbuf);
- x_free(str);
-
- str = acr_wbuf_data(&sbuf);
- return str;
-}
-
-ACR_DECLARE(int) ACR_StringToArgvW(const wchar_t *cmdline,
- wchar_t ***argv)
-{
- const wchar_t *cp;
- const wchar_t *ct;
- wchar_t *cleaned, *dirty;
- wchar_t *args;
- wchar_t *argp;
- wchar_t *exps;
- int escaped;
- int isquoted, numargs = 0, argnum;
- size_t offset;
-#define SKIP_WHITESPACEW(C) \
- for ( ; *C == L' ' || *C == L'\t'; ) { \
- C++; \
- };
-
-#define CHECK_QUOTATIONW(C, Q) \
- Q = 0; \
- if (*C == L'"') { \
- Q = 1; \
- C++; \
- } \
- else if (*C == L'\'') { \
- Q = 2; \
- C++; \
- }
-
-/* DETERMINE_NEXTSTRING:
- * At exit, cp will point to one of the following: NULL, SPACE, TAB or QUOTE.
- * NULL implies the argument string has been fully traversed.
- */
-#define DETERMINE_NEXTSTRINGW(C, Q) \
- for ( ; *C != L'\0'; C++) { \
- if ((*C == L'\\' && (*(C+1) == L' ' || *(C+1) == L'\t' || \
- *(C+1) == L'"' || *(C+1) == L'\''))) { \
- C++; \
- continue; \
- } \
- if ((!Q && (*C == L' ' || *C == L'\t')) \
- || (Q == 1 && *C == L'"') \
- || (Q == 2 && *C == L'\'')) { \
- break; \
- } \
- }
-
-/* REMOVE_ESCAPE_CHARS:
- * Compresses the arg string to remove all of the '\' escape chars.
- * The final argv strings should not have any extra escape chars in it.
- */
-#define REMOVE_ESCAPE_CHARSW(C, D, E) \
- E = 0; \
- while(*D) { \
- if (!E && *D == L'\\') { \
- E = 1; \
- } \
- else { \
- E = 0; \
- *C++ = *D; \
- } \
- ++D; \
- } \
- *C = 0
-
- cp = cmdline;
- SKIP_WHITESPACEW(cp);
- exps = x_wcsdup(cp);
- if (!exps)
- return -1;
- exps = _wcsexpand(exps);
- ct = exps;
-
- /* This is ugly and expensive, but if anyone wants to figure a
- * way to support any number of args without counting and
- * allocating, please go ahead and change the code.
- *
- * Must account for the trailing NULL arg.
- */
- numargs = 1;
- while (*ct != L'\0') {
- CHECK_QUOTATIONW(ct, isquoted);
- DETERMINE_NEXTSTRINGW(ct, isquoted);
- if (*ct != L'\0') {
- ct++;
- }
- numargs++;
- SKIP_WHITESPACEW(ct);
- }
- if (!argv) {
- x_free(exps);
- return numargs;
- }
- offset = ACR_ALIGN_DEFAULT(numargs * sizeof(wchar_t*));
- args = x_malloc(offset + ((wcslen(exps) + 1) * sizeof(wchar_t)));
- if (!args) {
- x_free(exps);
- return -1;
- }
- *argv = (wchar_t **)args;
- args += (offset / sizeof(wchar_t));
- wcscpy(args, exps);
- x_free(exps);
- /* determine first argument */
- for (argnum = 0; argnum < (numargs-1); argnum++) {
- SKIP_WHITESPACEW(args);
- CHECK_QUOTATIONW(args, isquoted);
- argp = args;
- DETERMINE_NEXTSTRINGW(args, isquoted);
- args++;
- (*argv)[argnum] = argp;
- (*argv)[argnum][args - argp - 1] = L'\0';
-
- cleaned = dirty = (*argv)[argnum];
- REMOVE_ESCAPE_CHARSW(cleaned, dirty, escaped);
- }
- /* Always NULL terminate the array */
- (*argv)[argnum] = NULL;
-
- return argnum;
-}
-
-#endif /* WIN32 */
-
-
ACR_DECLARE(char **) ACR_MergeArgsA(const char *const *argv1,
const char *const *argv2)
{
- size_t arglen;
- size_t argnum = 1;
- size_t length = 0;
- char *buffer;
- char **dupargv = NULL;
+ size_t argnum = 0;
+ char **dupargv = NULL;
const char *const *ap1 = argv1;
const char *const *ap2 = argv2;
- if (ap1) {
- while (*ap1) {
+ if (!argv1)
+ return NULL;
+ while (*ap1) {
+ if (**ap1)
++argnum;
- length += (strlen(*ap1) + 1);
- ap1++;
- }
+ ap1++;
}
+
if (ap2) {
while (*ap2) {
- ++argnum;
- length += (strlen(*ap2) + 1);
+ if (**ap2)
+ ++argnum;
ap2++;
}
}
- if (!length) {
+ if (!argnum) {
/* Nothing to duplicate
*/
return NULL;
}
- arglen = ACR_ALIGN_DEFAULT(argnum * sizeof(char *));
- buffer = x_malloc(arglen + length + 1);
- if (!buffer)
+ dupargv = s_malloc(char *, argnum + 1);
+ if (!dupargv)
return NULL;
argnum = 0;
ap1 = argv1;
ap2 = argv2;
- dupargv = (char **)buffer;
- buffer += arglen;
if (ap1) {
while (*ap1) {
- arglen = strlen(*ap1) + 1;
- memcpy(buffer, *ap1, arglen);
- dupargv[argnum++] = buffer;
- buffer += arglen;
+ if (**ap1) {
+ dupargv[argnum++] = (char *)*ap1;
+ }
ap1++;
}
}
if (ap2) {
while (*ap2) {
- arglen = strlen(*ap2) + 1;
- memcpy(buffer, *ap2, arglen);
- dupargv[argnum++] = buffer;
- buffer += arglen;
+ if (**ap2) {
+ dupargv[argnum++] = (char *)*ap2;
+ }
ap2++;
}
}
- *buffer = '\0';
+ /* Add terminating NULL pointer.
+ */
dupargv[argnum] = NULL;
return dupargv;
@@ -583,88 +341,174 @@
ACR_DECLARE(wchar_t **) ACR_MergeArgsW(const wchar_t *const *argv1,
const wchar_t *const *argv2)
{
- size_t arglen;
- size_t argnum = 1;
- size_t length = 0;
- wchar_t *buffer;
+ size_t argnum = 0;
wchar_t **dupargv = NULL;
const wchar_t *const *ap1 = argv1;
const wchar_t *const *ap2 = argv2;
- if (ap1) {
- while (*ap1) {
+ if (!argv1)
+ return NULL;
+ while (*ap1) {
+ if (**ap1)
++argnum;
- length += (wcslen(*ap1) + 1);
- ap1++;
- }
+ ap1++;
}
+
if (ap2) {
while (*ap2) {
- ++argnum;
- length += (wcslen(*ap2) + 1);
+ if (**ap2)
+ ++argnum;
ap2++;
}
}
- if (!length) {
+ if (!argnum) {
/* Nothing to duplicate
*/
return NULL;
}
- arglen = ACR_ALIGN_DEFAULT(argnum * sizeof(wchar_t *));
- buffer = x_malloc(arglen + ((length + 3) * sizeof(wchar_t)));
- if (!buffer)
+ dupargv = s_malloc(wchar_t *, argnum + 1);
+ if (!dupargv)
return NULL;
argnum = 0;
ap1 = argv1;
ap2 = argv2;
- dupargv = (wchar_t **)buffer;
- buffer += (arglen / sizeof(wchar_t));
if (ap1) {
while (*ap1) {
- arglen = wcslen(*ap1) + 1;
- if (argnum == 0 && wcspbrk(*ap1, L" \t")) {
- buffer[0] = L'"';
- memcpy(buffer + 1, *ap1, arglen * sizeof(wchar_t));
- buffer[arglen + 1] = L'"';
+ if (**ap1) {
+ dupargv[argnum++] = (wchar_t *)*ap1;
}
- else
- memcpy(buffer, *ap1, arglen * sizeof(wchar_t));
- dupargv[argnum++] = buffer;
- buffer += arglen;
ap1++;
}
}
if (ap2) {
while (*ap2) {
- arglen = wcslen(*ap2) + 1;
- if (argnum == 0 && wcspbrk(*ap2, L" \t")) {
- buffer[0] = L'"';
- memcpy(buffer + 1, *ap2, arglen * sizeof(wchar_t));
- buffer[arglen + 1] = L'"';
+ if (**ap2) {
+ dupargv[argnum++] = (wchar_t *)*ap2;
}
- else
- memcpy(buffer, *ap2, arglen * sizeof(wchar_t));
- dupargv[argnum++] = buffer;
- buffer += arglen;
ap2++;
}
}
- /* Add double zero termination.
- * dupargv[0] can be used as zero separated
- * double zero terminated string
+ /* Add terminating NULL pointer.
*/
- *buffer = L'\0';
dupargv[argnum] = NULL;
return dupargv;
}
-ACR_DECLARE(char **) ACR_DuplicateArgsA(const char *const *argv)
+ACR_DECLARE(char *) ACR_ArgsToStringA(const char *const *argv)
+{
+ size_t argnum = 0;
+ size_t length = 0;
+ size_t arglen = 0;
+ const char *const *ap = argv;
+ char *args, *cp;
+
+ if (!ap) {
+ ACR_SET_OS_ERROR(ACR_EILSEQ);
+ return NULL;
+ }
+ while (*ap) {
+ size_t al = strquote(*ap, NULL, 0);
+ if (al == (size_t) -1) {
+ ACR_SET_OS_ERROR(ACR_EILSEQ);
+ return NULL;
+ }
+ length += (al + 1);
+ ap++;
+ }
+ if (length == 0)
+ return NULL;
+ args = cp = s_malloc(char, length + 1);
+ if (!args)
+ return NULL;
+ ap = argv;
+
+ while (*ap) {
+ if (argnum++) {
+ *(cp++) = ' ';
+ --length;
+ }
+ arglen = strquote(*ap, cp, length);
+ cp += arglen;
+ length -= arglen;
+ ap++;
+ }
+ *cp = '\0';
+ return args;
+}
+
+ACR_DECLARE(wchar_t *) ACR_ArgsToStringW(const wchar_t *const *argv)
{
- return ACR_MergeArgsA(argv, NULL);
+ size_t argnum = 0;
+ size_t length = 0;
+ size_t arglen = 0;
+ const wchar_t *const *ap = argv;
+ wchar_t *args, *cp;
+
+ if (!ap) {
+ ACR_SET_OS_ERROR(ACR_EILSEQ);
+ return NULL;
+ }
+ while (*ap) {
+ size_t al = wcsquote(*ap, NULL, 0);
+ if (al == (size_t) -1) {
+ ACR_SET_OS_ERROR(ACR_EILSEQ);
+ return NULL;
+ }
+ length += (al + 1);
+ ap++;
+ }
+ if (length == 0)
+ return NULL;
+ args = cp = s_malloc(wchar_t, length + 1);
+ if (!args)
+ return NULL;
+ ap = argv;
+
+ while (*ap) {
+ if (argnum++) {
+ *(cp++) = L' ';
+ --length;
+ }
+ arglen = wcsquote(*ap, cp, length);
+ cp += arglen;
+ length -= arglen;
+ ap++;
+ }
+ *cp = L'\0';
+ return args;
+}
+
+static int _strcompare(const void *arg1, const void *arg2)
+{
+ /* Compare all of both strings: */
+ return strcasecmp(*((const char **)arg1),
+ *((const char **)arg2));
+}
+
+static int _wcscompare(const void *arg1, const void *arg2)
+{
+ /* Compare all of both strings: */
+ return wcscasecmp(*((const wchar_t **)arg1),
+ *((const wchar_t **)arg2));
+}
+
+ACR_DECLARE(void) ACR_ArgsSortA(char *const **args)
+{
+ size_t len = 0;
+ char *const *sa = *args;
+
+ while (sa[len])
+ len++;
+ qsort((void *)&args, len, sizeof(char *), _strcompare);
}
-ACR_DECLARE(wchar_t **) ACR_DuplicateArgsW(const wchar_t *const *argv)
+ACR_DECLARE(void) ACR_ArgsSortW(wchar_t *const **args)
{
- return ACR_MergeArgsW(argv, NULL);
+ size_t len = 0;
+ wchar_t *const *sa = *args;
+
+ while (sa[len])
+ len++;
+ qsort((void *)&args, len, sizeof(wchar_t *), _wcscompare);
}
Modified: commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c?rev=897765&r1=897764&r2=897765&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c Mon Jan 11 06:51:28 2010
@@ -56,8 +56,8 @@
#define SBUF_ISDYNSTRUCT(s) ((s)->s_flags & ACR_SBUF_DYNSTRUCT)
#define SBUF_ISFINISHED(s) ((s)->s_flags & ACR_SBUF_FINISHED)
#define SBUF_HASOVERFLOWED(s) ((s)->s_flags & ACR_SBUF_OVERFLOWED || (s)->s_buf == NULL)
-#define SBUF_HASROOM(s) ((s)->s_len < ((s)->s_size - 2))
-#define SBUF_FREESPACE(s) ((s)->s_size - ((s)->s_len - 2))
+#define SBUF_HASROOM(s) ((s)->s_len < ((s)->s_size - 1))
+#define SBUF_FREESPACE(s) ((s)->s_size - ((s)->s_len - 1))
#define SBUF_CANEXTEND(s) ((s)->s_flags & ACR_SBUF_AUTOEXTEND)
/*
@@ -434,8 +434,7 @@
acr_sbuf_finish(acr_sbuf_t *s)
{
if (s->s_buf) {
- s->s_buf[s->s_len++] = '\0';
- s->s_buf[s->s_len] = '\0';
+ s->s_buf[s->s_len] = '\0';
SBUF_CLRFLAG(s, ACR_SBUF_OVERFLOWED);
}
SBUF_SETFLAG(s, ACR_SBUF_FINISHED);
@@ -776,9 +775,7 @@
acr_wbuf_finish(acr_wbuf_t *s)
{
if (s->s_buf) {
- s->s_buf[s->s_len++] = L'\0';
- s->s_buf[s->s_len] = L'\0';
-
+ s->s_buf[s->s_len] = L'\0';
SBUF_CLRFLAG(s, ACR_SBUF_OVERFLOWED);
}
SBUF_SETFLAG(s, ACR_SBUF_FINISHED);
Modified: commons/sandbox/runtime/trunk/src/main/native/shared/string.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/string.c?rev=897765&r1=897764&r2=897765&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/string.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/string.c Mon Jan 11 06:51:28 2010
@@ -281,6 +281,114 @@
return ACR_SUCCESS;
}
+static int conv_utf8_to_wcs(const char *in, size_t inbytes,
+ wchar_t *out, size_t *outwords)
+{
+ acr_int64_t newch, mask;
+ size_t expect, eating;
+ int ch;
+
+ while (inbytes && *outwords) {
+ ch = (unsigned char)(*in++);
+ if (!(ch & 0200)) {
+ /* US-ASCII-7 plain text
+ */
+ --inbytes;
+ --*outwords;
+ *(out++) = ch;
+ }
+ else {
+ if ((ch & 0300) != 0300) {
+ /* Multibyte Continuation is out of place
+ */
+ return ACR_EINVAL;
+ }
+ else {
+ /* Multibyte Sequence Lead Character
+ *
+ * Compute the expected bytes while adjusting
+ * or lead byte and leading zeros mask.
+ */
+ mask = 0340;
+ expect = 1;
+ while ((ch & mask) == mask) {
+ mask |= mask >> 1;
+ if (++expect > 3) /* (truly 5 for ucs-4) */
+ return ACR_EINVAL;
+ }
+ newch = ch & ~mask;
+ eating = expect + 1;
+ if (inbytes <= expect)
+ return ACR_INCOMPLETE;
+ /* Reject values of excessive leading 0 bits
+ * utf-8 _demands_ the shortest possible byte length
+ */
+ if (expect == 1) {
+ if (!(newch & 0036))
+ return ACR_EINVAL;
+ }
+ else {
+ /* Reject values of excessive leading 0 bits
+ */
+ if (!newch && !((unsigned char)*in & 0077 & (mask << 1)))
+ return ACR_EINVAL;
+ if (expect == 2) {
+ /* Reject values D800-DFFF when not utf16 encoded
+ * (may not be an appropriate restriction for ucs-4)
+ */
+ if (newch == 0015 && ((unsigned char)*in & 0040))
+ return ACR_EINVAL;
+ }
+ else if (expect == 3) {
+ /* Short circuit values > 110000
+ */
+ if (newch > 4)
+ return ACR_EINVAL;
+ if (newch == 4 && ((unsigned char)*in & 0060))
+ return ACR_EINVAL;
+ }
+ }
+ /* Where the boolean (expect > 2) is true, we will need
+ * an extra word for the output.
+ */
+ if (*outwords < (size_t)(expect > 2) + 1)
+ break; /* buffer full */
+ while (expect--) {
+ /* Multibyte Continuation must be legal */
+ if (((ch = (unsigned char)*(in++)) & 0300) != 0200)
+ return ACR_EINVAL;
+ newch <<= 6;
+ newch |= (ch & 0077);
+ }
+ inbytes -= eating;
+#if CC_SIZEOF_WCHAR_T == 2
+ /* newch is now a true ucs-4 character
+ *
+ * now we need to fold to ucs-2
+ */
+ if (newch < 0x10000) {
+ --*outwords;
+ *(out++) = (wchar_t) newch;
+ }
+ else {
+ *outwords -= 2;
+ newch -= 0x10000;
+ *(out++) = (wchar_t) (0xD800 | (newch >> 10));
+ *(out++) = (wchar_t) (0xDC00 | (newch & 0x03FF));
+ }
+#else
+ --*outwords;
+ *(out++) = (wchar_t) newch;
+#endif
+ }
+ }
+ }
+ /* Buffer full 'errors' aren't errors, the client must inspect both
+ * the inbytes and outwords values
+ */
+ return ACR_SUCCESS;
+}
+
/* Java implementation of GetStringUTF is bogus.
* It breaks on embeded NUL in strings.
* Use the APR implementation instead.
@@ -506,6 +614,25 @@
return dst;
}
+ACR_DECLARE(wchar_t *) ACR_Utf8ToWcs(JNIEnv *_E, const char *str)
+{
+ int rc;
+ size_t len, out;
+ wchar_t *dst;
+
+ out = len = strlen(str) + 1;
+ dst = ACR_MALLOC(wchar_t, len);
+ if (!dst)
+ return NULL;
+ if ((rc = conv_utf8_to_wcs(str, len, dst, &out))) {
+ /* Invalid UTF-8 string */
+ x_free(dst);
+ ACR_SET_OS_ERROR(rc);
+ return NULL;
+ }
+ return dst;
+}
+
ACR_DECLARE(char *) ACR_Usc2ToUtf8(JNIEnv *_E, const jchar *str, jsize len)
{
int rc;
@@ -1919,7 +2046,7 @@
return NULL;
cnt = (*_E)->GetArrayLength(_E, arr);
- ret = (char **)ACR_Malloc(_E, THROW_NMARK, (cnt + 1) * sizeof(char *));
+ ret = (char **)ACR_MALLOC(char *, cnt + 1);
if (!ret)
return NULL;
for (i = 0; i < cnt; i++) {
@@ -1945,7 +2072,7 @@
return NULL;
cnt = (*_E)->GetArrayLength(_E, arr);
- ret = (wchar_t **)ACR_Malloc(_E, THROW_NMARK, (cnt + 1) * sizeof(wchar_t *));
+ ret = (wchar_t **)ACR_MALLOC(wchar_t *, cnt + 1);
if (!ret)
return NULL;
for (i = 0; i < cnt; i++) {
@@ -1961,16 +2088,15 @@
return ret;
}
-ACR_DECLARE(char **) ACR_MszStrToArrayA(JNIEnv *_E,
- const char *str)
+ACR_DECLARE(char **) ACR_MszStrToArrayA(const char *str)
{
char **arr = NULL;
- jsize n = 0;
+ size_t n = 0;
const char *p;
if (str) {
- if ((n = (jsize)ACR_MszStrCountA(str)) > 0)
- arr = ACR_Malloc(_E, THROW_FMARK, (n + 1) * sizeof(char *));
+ if ((n = ACR_MszStrCountA(str)) > 0)
+ arr = s_malloc(char *, n + 1);
}
if (!arr)
return NULL;
@@ -1985,16 +2111,15 @@
return arr;
}
-ACR_DECLARE(wchar_t **) ACR_MszStrToArrayW(JNIEnv *_E,
- const wchar_t *str)
+ACR_DECLARE(wchar_t **) ACR_MszStrToArrayW(const wchar_t *str)
{
wchar_t **arr = NULL;
- jsize n = 0;
+ size_t n = 0;
const wchar_t *p;
if (str) {
- if ((n = (jsize)ACR_MszStrCountW(str)) > 0)
- arr = ACR_Malloc(_E, THROW_FMARK, (n + 1) * sizeof(wchar_t *));
+ if ((n = ACR_MszStrCountW(str)) > 0)
+ arr = s_malloc(wchar_t *, n + 1);
}
if (!arr)
return NULL;
@@ -2009,6 +2134,84 @@
return arr;
}
+ACR_DECLARE(char *) ACR_ArrayToMszStrA(const char *const *arr)
+{
+ const char *const *ap = arr;
+ size_t n = 0;
+ size_t l = 0;
+ char *p, *s;
+
+ if (!arr)
+ return NULL;
+
+ while(*ap) {
+ ++n;
+ if (**ap)
+ l += (strlen(*ap) + 1);
+ ap++;
+ }
+ if (l == 0) {
+ /* Nothing to duplicate
+ */
+ return NULL;
+ }
+ ap = arr;
+ p = s = s_malloc(char, l + 1);
+ if (!p)
+ return NULL;
+
+ while(*ap) {
+ if (**ap) {
+ l = strlen(*ap);
+ memcpy(p, *ap, l);
+ p += l;
+ *p++ = '\0';
+ }
+ ap++;
+ }
+ *p = '\0';
+ return s;
+}
+
+ACR_DECLARE(wchar_t *) ACR_ArrayToMszStrW(const wchar_t *const *arr)
+{
+ const wchar_t *const *ap = arr;
+ size_t n = 0;
+ size_t l = 0;
+ wchar_t *p, *s;
+
+ if (!arr)
+ return NULL;
+
+ while(*ap) {
+ ++n;
+ if (**ap)
+ l += (wcslen(*ap) + 1);
+ ap++;
+ }
+ if (l == 0) {
+ /* Nothing to duplicate
+ */
+ return NULL;
+ }
+ ap = arr;
+ p = s = s_malloc(wchar_t, l + 1);
+ if (!p)
+ return NULL;
+
+ while(*ap) {
+ if (**ap) {
+ l = wcslen(*ap);
+ memcpy(p, *ap, l * sizeof(wchar_t));
+ p += l;
+ *p++ = L'\0';
+ }
+ ap++;
+ }
+ *p = L'\0';
+ return s;
+}
+
ACR_DECLARE(char *) ACR_strqtab2ss(char *str)
{
char *ptr = str;
@@ -2058,36 +2261,3 @@
}
return ptr;
}
-
-static int _strcompare(const void *arg1, const void *arg2)
-{
- /* Compare all of both strings: */
- return strcasecmp(*(char **)arg1, *(char **)arg2);
-}
-
-static int _wcscompare(const void *arg1, const void *arg2)
-{
- /* Compare all of both strings: */
- return wcscasecmp(*(wchar_t **)arg1, *(wchar_t **)arg2);
-}
-
-ACR_DECLARE(void) ACR_StrArraySortA(char ***args)
-{
- size_t len = 0;
- char **sa = *args;
-
- while (sa[len])
- len++;
- qsort((void *)&args, len, sizeof(char *), _strcompare);
-}
-
-ACR_DECLARE(void) ACR_StrArraySortW(wchar_t ***args)
-{
- size_t len = 0;
- wchar_t **sa = *args;
-
- while (sa[len])
- len++;
- qsort((void *)&args, len, sizeof(wchar_t *), _wcscompare);
-}
-
Modified: commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c?rev=897765&r1=897764&r2=897765&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c Mon Jan 11 06:51:28 2010
@@ -577,7 +577,6 @@
return ACR_EINVAL;
}
exe = ACR_ExecNew(ACR_PROC_HAS_STDOUT);
- printf("Exec is %p\n", exe);
exe->limit.timeout = ACR_USEC_PER_SEC * 2;
#if defined(WIN32)
rc = ACR_ExecShellCmd(exe, wargv[0], NULL);