newlib/winsup/cygwin/winf.h
Christopher Faylor 521953a83a * 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.
2013-07-19 17:28:34 +00:00

107 lines
2.9 KiB
C++

/* winf.h
Copyright 2006, 2007, 2009, 2011, 2013 Red Hat, Inc.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#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
processes get the full command line as argv array anyway, this only affects
the maximum command line length of Cygwin applications which nonsensically
have a WinMain instead of a main entry point or which use GetCommandLine. */
#define MAXCYGWINCMDLEN 30000
#define MAXWINCMDLEN 32767
#define LINE_BUF_CHUNK (MAX_PATH * 2)
class av
{
char **argv;
int calloced;
public:
int argc;
bool win16_exe;
av (): argv (NULL) {}
av (int ac_in, const char * const *av_in) : calloced (0), argc (ac_in), win16_exe (false)
{
argv = (char **) cmalloc_abort (HEAP_1_ARGV, (argc + 5) * sizeof (char *));
memcpy (argv, av_in, (argc + 1) * sizeof (char *));
}
void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;}
~av ()
{
if (argv)
{
for (int i = 0; i < calloced; i++)
cfree (argv[i]);
cfree (argv);
}
}
int unshift (const char *what, int conv = 0) __reg2;
operator char **() {return argv;}
void all_calloced () {calloced = argc;}
void replace0_maybe (const char *arg0)
{
/* Note: Assumes that argv array has not yet been "unshifted" */
if (!calloced)
{
argv[0] = cstrdup1 (arg0);
calloced = 1;
}
}
void dup_all ()
{
for (int i = calloced; i < argc; i++)
argv[i] = cstrdup1 (argv[i]);
calloced = argc;
}
int setup (const char *, path_conv&, const char *, int, const char *const *,
bool) __reg3;
};
class linebuf
{
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 add (const char *what) {add (what, strlen (what));}
void prepend (const char *, int);
void __reg2 finish (bool);
bool __reg3 fromargv(av&, const char *, bool);;
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;
}
};
/* 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; \
})