* 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.
+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
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
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
/* 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.
#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. */
}
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;
+}
}
av newargv;
- linebuf one_line;
+ linebuf cmd;
PWCHAR envblock = NULL;
path_conv real_path;
bool reset_sendsig = false;
(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;
}
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;
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;
goto out;
}
}
- syscall_printf ("null_app_name %d (%W, %.9500W)", null_app_name,
- runpath, wone_line);
cygbench ("spawn-worker");
&& !::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 */
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 */
/* 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);
-/* 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.
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
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);
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; \
+})