* common.din: Export GetCommandLine{A,W}.

* kernel32.cc: Add includes needed for GetCommandLine functions.
(ucmd): New function.
(cygwin_GetCommandLineW): Ditto.
(cygwin_GetCommandLineA): Ditto.
* spawn.cc (child_info_spawn::worker): Rename one_line -> cmd.  Use lb_wcs
macro to generate a wide character version of the line buffer.  Remove
duplicate printing of command line.  Don't access members of linebuf directly.
* winf.h: Use pragma once.
(linebuf): Make storage private.
(linebuf::operator size_t): New operator.  Return size of buf.
(linebuf::operator wchar_t): New operator.
(linebuf::wcs): New function.
(lb_wcs): New macro.
* include/cygwin/version.h: Bump API minor number to 268.
* strfuncs.cc: Clarify descriptive file comment.
This commit is contained in:
Christopher Faylor 2013-07-19 17:28:34 +00:00
parent 4b25516b5d
commit 521953a83a
7 changed files with 117 additions and 29 deletions

View File

@ -1,3 +1,24 @@
2013-07-19 Christopher Faylor <me.cygwin2013@cgf.cx>
* common.din: Export GetCommandLine{A,W}.
* kernel32.cc: Add includes needed for GetCommandLine functions.
(ucmd): New function.
(cygwin_GetCommandLineW): Ditto.
(cygwin_GetCommandLineA): Ditto.
* spawn.cc (child_info_spawn::worker): Rename one_line -> cmd. Use
linebuf_wcs macro to generate a wide character version of the
line buffer. Remove duplicate printing of command line. Don't access
members of linebuf directly.
* winf.h: Use pragma once.
(linebuf): Make storage private.
(linebuf::operator size_t): New operator. Return size of buf.
(linebuf::operator wchar_t): New operator.
(linebuf::wcs): New function.
(lb_wcs): New macro.
* include/cygwin/version.h: Bump API minor number to 268.
* strfuncs.cc: Clarify descriptive file comment.
2013-07-19 Corinna Vinschen <corinna@vinschen.de>
* cygtls.cc (_cygtls::remove): Close cw_timer handle, thus avoiding

View File

@ -457,6 +457,8 @@ gammaf NOSIGFE
gammaf_r NOSIGFE
gcvt SIGFE
gcvtf SIGFE
GetCommandLineA@0 = cygwin_GetCommandLineA@0 NOSIGFE
GetCommandLineW@0 = cygwin_GetCommandLineW@0 NOSIGFE
get_avphys_pages SIGFE
get_current_dir_name SIGFE
get_nprocs SIGFE

View File

@ -437,12 +437,13 @@ details. */
266: Export arc4random, arc4random_addrandom, arc4random_buf,
arc4random_stir, arc4random_uniform.
267: Export rawmemchr.
268: Export GetCommandLineA, GetCommandLineW
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 267
#define CYGWIN_VERSION_API_MINOR 268
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible

View File

@ -1,6 +1,6 @@
/* kernel32.cc: Win32 replacement functions.
Copyright 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
Copyright 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@ -11,6 +11,15 @@ details. */
#include "winsup.h"
#include "shared_info.h"
#include "ntdll.h"
#include "cygerrno.h"
#include "security.h"
#include "path.h"
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"
#include "tls_pbuf.h"
#include "winf.h"
#include "sys/cygwin.h"
/* Implement CreateEvent/OpenEvent so that named objects are always created in
Cygwin shared object namespace. */
@ -402,3 +411,43 @@ OpenFileMappingA (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
}
return OpenFileMappingW (dwDesiredAccess, bInheritHandle, lpName ? name : NULL);
}
/* The external functions below wrap Windows functions of the same name
and provide a Windows interface to Cygwin functionality. */
/* Construct a unicode version of the Cygwin command line from __argv) */
static UNICODE_STRING *
ucmd ()
{
static UNICODE_STRING wcmd;
if (!wcmd.Buffer)
{
linebuf cmd;
path_conv real_path (__argv[0]);
av newargv (__argc, __argv);
cmd.fromargv (newargv, real_path.get_win32 (), true);
RtlInitUnicodeString (&wcmd, cmd);
}
return &wcmd;
}
/* Cygwin replacement for GetCommandLineA. Returns a concatenated wide string
representing the argv list, constructed using roughly the same mechanism as
child_info_spawn::worker */
extern "C" LPWSTR WINAPI
cygwin_GetCommandLineW (void)
{
return ucmd ()->Buffer;
}
/* Cygwin replacement for GetCommandLineA. Returns a concatenated string
representing the argv list, constructed using roughly the same mechanism
as child_info_spawn::worker */
extern "C" LPSTR WINAPI
cygwin_GetCommandLineA (void)
{
static ANSI_STRING cmd;
if (!cmd.Buffer)
RtlUnicodeStringToAnsiString (&cmd, ucmd (), TRUE);
return cmd.Buffer;
}

View File

@ -319,7 +319,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
}
av newargv;
linebuf one_line;
linebuf cmd;
PWCHAR envblock = NULL;
path_conv real_path;
bool reset_sendsig = false;
@ -387,16 +387,16 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
(iscmd (argv[0], "command.com") || iscmd (argv[0], "cmd.exe")))
{
real_path.check (prog_arg);
one_line.add ("\"");
cmd.add ("\"");
if (!real_path.error)
one_line.add (real_path.get_win32 ());
cmd.add (real_path.get_win32 ());
else
one_line.add (argv[0]);
one_line.add ("\"");
one_line.add (" ");
one_line.add (argv[1]);
one_line.add (" ");
one_line.add (argv[2]);
cmd.add (argv[0]);
cmd.add ("\"");
cmd.add (" ");
cmd.add (argv[1]);
cmd.add (" ");
cmd.add (argv[2]);
real_path.set_path (argv[0]);
null_app_name = true;
}
@ -407,7 +407,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
moreinfo->argc = newargv.argc;
moreinfo->argv = newargv;
}
else if (!one_line.fromargv (newargv, real_path.get_win32 (),
else if (!cmd.fromargv (newargv, real_path.get_win32 (),
real_path.iscygexec ()))
{
res = -1;
@ -423,11 +423,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
else
VerifyHandle (moreinfo->myself_pinfo);
}
WCHAR wone_line[one_line.ix + 1];
if (one_line.ix)
sys_mbstowcs (wone_line, one_line.ix + 1, one_line.buf);
else
wone_line[0] = L'\0';
PROCESS_INFORMATION pi;
pi.hProcess = pi.hThread = NULL;
@ -539,8 +534,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
goto out;
}
}
syscall_printf ("null_app_name %d (%W, %.9500W)", null_app_name,
runpath, wone_line);
cygbench ("spawn-worker");
@ -626,7 +619,7 @@ loop:
&& !::cygheap->user.setuid_to_restricted))
{
rc = CreateProcessW (runpath, /* image name - with full path */
wone_line, /* what was passed to exec */
lb_wcs (cmd), /* what was passed to exec */
&sec_none_nih, /* process security attrs */
&sec_none_nih, /* thread security attrs */
TRUE, /* inherit handles from parent */
@ -689,7 +682,7 @@ loop:
rc = CreateProcessAsUserW (::cygheap->user.primary_token (),
runpath, /* image name - with full path */
wone_line, /* what was passed to exec */
lb_wcs (cmd), /* what was passed to exec */
&sec_none_nih, /* process security attrs */
&sec_none_nih, /* thread security attrs */
TRUE, /* inherit handles from parent */
@ -763,7 +756,7 @@ loop:
/* We print the original program name here so the user can see that too. */
syscall_printf ("pid %d, prog_arg %s, cmd line %.9500s)",
rc ? cygpid : (unsigned int) -1, prog_arg, one_line.buf);
rc ? cygpid : (unsigned int) -1, prog_arg, (const char *) cmd);
/* Name the handle similarly to proc_subproc. */
ProtectHandle1 (pi.hProcess, childhProc);

View File

@ -1,4 +1,4 @@
/* strfuncs.cc: misc funcs that don't belong anywhere else
/* strfuncs.cc: string functions
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.

View File

@ -6,9 +6,7 @@ This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#ifndef _WINF_H
#define _WINF_H
#pragma once
/* Hack for Cygwin processes. If the Windows command line length gets slightly
bigger than this value, the stack position is suddenly moved up by 64K for
no apparent reason, which results in subsequent forks failing. Since Cygwin
@ -67,10 +65,10 @@ class av
class linebuf
{
public:
size_t ix;
char *buf;
size_t alloced;
public:
linebuf () : ix (0), buf (NULL), alloced (0) {}
~linebuf () {if (buf) free (buf);}
void __reg3 add (const char *, int);
@ -78,7 +76,31 @@ class linebuf
void prepend (const char *, int);
void __reg2 finish (bool);
bool __reg3 fromargv(av&, const char *, bool);;
operator char *() {return buf;}
operator size_t () const { return ix + 1; }
operator const char * () const { return buf; }
operator wchar_t * ()
{
size_t n = ix + 1;
/* Note that this malloc'ed buffer is not freed by the destructor.
It is up to the caller to do (or not do) that. */
wchar_t *wbuf = (wchar_t *) malloc (sizeof (wchar_t) * n);
return wcs (wbuf, n);
}
wchar_t *wcs (wchar_t *wbuf, size_t n)
{
if (n == 1)
wbuf[0] = L'\0';
else
sys_mbstowcs (wbuf, n, buf);
return wbuf;
}
};
#endif /*_WINF_H*/
/* Return a temporary buffer representing the wide character version
of a linebuf command line. */
#define lb_wcs(__x) \
({ \
wchar_t __wbuf[(size_t) __x]; \
__x.wcs (__wbuf, sizeof (__wbuf) / sizeof (__wbuf[0])); \
__wbuf; \
})