Cygwin: redefine CW_CMDLINE to CW_CMDLINE_ALLOC

Make sure to

- append a trailing \0 as with Windows multistrings, so the end of
  the string can be recognized by the caller, and

- allocate cmdline on the user heap so the caller can free the
  multistring after usage.

Fixes: 831d6fa520 ("* external.cc (cygwin_internal): Implement CW_CMDLINE.")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2024-01-30 20:46:09 +01:00
parent b1d64ac265
commit 732afede93
2 changed files with 41 additions and 4 deletions

View file

@ -344,20 +344,37 @@ cygwin_internal (cygwin_getinfo_types t, ...)
res = 0; res = 0;
} }
break; break;
case CW_CMDLINE:
case CW_CMDLINE_ALLOC:
{ {
size_t n; size_t n;
char *cmdline_cheap;
char *cmdline;
pid_t pid = va_arg (arg, pid_t); pid_t pid = va_arg (arg, pid_t);
pinfo p (pid); pinfo p (pid);
res = (uintptr_t) (p ? p->cmdline (n) : NULL); cmdline_cheap = (p ? p->cmdline (n) : NULL);
if (cmdline_cheap)
{
cmdline = (char *) malloc (n + 1);
if (cmdline)
{
memcpy (cmdline, cmdline_cheap, n);
cmdline[n] = '\0';
}
cfree (cmdline_cheap);
}
res = (uintptr_t) cmdline;
} }
break; break;
case CW_CHECK_NTSEC: case CW_CHECK_NTSEC:
{ {
char *filename = va_arg (arg, char *); char *filename = va_arg (arg, char *);
res = check_ntsec (filename); res = check_ntsec (filename);
} }
break; break;
case CW_GET_ERRNO_FROM_WINERROR: case CW_GET_ERRNO_FROM_WINERROR:
{ {
int error = va_arg (arg, int); int error = va_arg (arg, int);
@ -365,6 +382,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
res = geterrno_from_win_error (error, deferrno); res = geterrno_from_win_error (error, deferrno);
} }
break; break;
case CW_GET_POSIX_SECURITY_ATTRIBUTE: case CW_GET_POSIX_SECURITY_ATTRIBUTE:
{ {
path_conv dummy; path_conv dummy;
@ -383,23 +401,27 @@ cygwin_internal (cygwin_getinfo_types t, ...)
} }
} }
break; break;
case CW_GET_SHMLBA: case CW_GET_SHMLBA:
{ {
res = wincap.allocation_granularity (); res = wincap.allocation_granularity ();
} }
break; break;
case CW_GET_UID_FROM_SID: case CW_GET_UID_FROM_SID:
{ {
cygpsid psid = va_arg (arg, PSID); cygpsid psid = va_arg (arg, PSID);
res = psid.get_uid (NULL); res = psid.get_uid (NULL);
} }
break; break;
case CW_GET_GID_FROM_SID: case CW_GET_GID_FROM_SID:
{ {
cygpsid psid = va_arg (arg, PSID); cygpsid psid = va_arg (arg, PSID);
res = psid.get_gid (NULL); res = psid.get_gid (NULL);
} }
break; break;
case CW_GET_BINMODE: case CW_GET_BINMODE:
{ {
const char *path = va_arg (arg, const char *); const char *path = va_arg (arg, const char *);
@ -413,6 +435,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
res = p.binmode (); res = p.binmode ();
} }
break; break;
case CW_HOOK: case CW_HOOK:
{ {
const char *name = va_arg (arg, const char *); const char *name = va_arg (arg, const char *);
@ -421,32 +444,39 @@ cygwin_internal (cygwin_getinfo_types t, ...)
res = (uintptr_t) hook_or_detect_cygwin (name, hookfn, subsys); res = (uintptr_t) hook_or_detect_cygwin (name, hookfn, subsys);
} }
break; break;
case CW_ARGV: case CW_ARGV:
{ {
child_info_spawn *ci = (child_info_spawn *) get_cygwin_startup_info (); child_info_spawn *ci = (child_info_spawn *) get_cygwin_startup_info ();
res = (uintptr_t) (ci ? ci->moreinfo->argv : NULL); res = (uintptr_t) (ci ? ci->moreinfo->argv : NULL);
} }
break; break;
case CW_ENVP: case CW_ENVP:
{ {
child_info_spawn *ci = (child_info_spawn *) get_cygwin_startup_info (); child_info_spawn *ci = (child_info_spawn *) get_cygwin_startup_info ();
res = (uintptr_t) (ci ? ci->moreinfo->envp : NULL); res = (uintptr_t) (ci ? ci->moreinfo->envp : NULL);
} }
break; break;
case CW_DEBUG_SELF: case CW_DEBUG_SELF:
error_start_init (va_arg (arg, const char *)); error_start_init (va_arg (arg, const char *));
res = try_to_debug (); res = try_to_debug ();
break; break;
case CW_SYNC_WINENV: case CW_SYNC_WINENV:
create_winenv (NULL); create_winenv (NULL);
res = 0; res = 0;
break; break;
case CW_CYGTLS_PADSIZE: case CW_CYGTLS_PADSIZE:
res = __CYGTLS_PADSIZE__; res = __CYGTLS_PADSIZE__;
break; break;
case CW_SET_DOS_FILE_WARNING: case CW_SET_DOS_FILE_WARNING:
res = 0; res = 0;
break; break;
case CW_SET_PRIV_KEY: case CW_SET_PRIV_KEY:
{ {
const char *passwd = va_arg (arg, const char *); const char *passwd = va_arg (arg, const char *);
@ -454,6 +484,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
res = setlsapwd (passwd, username); res = setlsapwd (passwd, username);
} }
break; break;
case CW_SETERRNO: case CW_SETERRNO:
{ {
const char *file = va_arg (arg, const char *); const char *file = va_arg (arg, const char *);
@ -462,6 +493,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
res = 0; res = 0;
} }
break; break;
case CW_EXIT_PROCESS: case CW_EXIT_PROCESS:
{ {
UINT status = va_arg (arg, UINT); UINT status = va_arg (arg, UINT);
@ -476,6 +508,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
res = 0; res = 0;
} }
break; break;
case CW_GET_INSTKEY: case CW_GET_INSTKEY:
{ {
PWCHAR dest = va_arg (arg, PWCHAR); PWCHAR dest = va_arg (arg, PWCHAR);
@ -483,6 +516,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
res = 0; res = 0;
} }
break; break;
case CW_INT_SETLOCALE: case CW_INT_SETLOCALE:
{ {
extern void internal_setlocale (); extern void internal_setlocale ();
@ -490,6 +524,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
res = 0; res = 0;
} }
break; break;
case CW_CVT_MNT_OPTS: case CW_CVT_MNT_OPTS:
{ {
extern bool fstab_read_flags (char **, unsigned &, bool); extern bool fstab_read_flags (char **, unsigned &, bool);
@ -509,6 +544,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
} }
} }
break; break;
case CW_LST_MNT_OPTS: case CW_LST_MNT_OPTS:
{ {
extern char *fstab_list_flags (); extern char *fstab_list_flags ();
@ -523,6 +559,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
} }
} }
break; break;
case CW_STRERROR: case CW_STRERROR:
{ {
int err = va_arg (arg, int); int err = va_arg (arg, int);

View file

@ -95,7 +95,7 @@ typedef enum
CW_STRACE_ACTIVE, CW_STRACE_ACTIVE,
CW_CYGWIN_PID_TO_WINPID, CW_CYGWIN_PID_TO_WINPID,
CW_EXTRACT_DOMAIN_AND_USER, CW_EXTRACT_DOMAIN_AND_USER,
CW_CMDLINE, CW_CMDLINE_ALLOC,
CW_CHECK_NTSEC, CW_CHECK_NTSEC,
CW_GET_ERRNO_FROM_WINERROR, CW_GET_ERRNO_FROM_WINERROR,
CW_GET_POSIX_SECURITY_ATTRIBUTE, CW_GET_POSIX_SECURITY_ATTRIBUTE,
@ -159,7 +159,7 @@ typedef enum
#define CW_STRACE_ACTIVE CW_STRACE_ACTIVE #define CW_STRACE_ACTIVE CW_STRACE_ACTIVE
#define CW_CYGWIN_PID_TO_WINPID CW_CYGWIN_PID_TO_WINPID #define CW_CYGWIN_PID_TO_WINPID CW_CYGWIN_PID_TO_WINPID
#define CW_EXTRACT_DOMAIN_AND_USER CW_EXTRACT_DOMAIN_AND_USER #define CW_EXTRACT_DOMAIN_AND_USER CW_EXTRACT_DOMAIN_AND_USER
#define CW_CMDLINE CW_CMDLINE #define CW_CMDLINE_ALLOC CW_CMDLINE_ALLOC
#define CW_CHECK_NTSEC CW_CHECK_NTSEC #define CW_CHECK_NTSEC CW_CHECK_NTSEC
#define CW_GET_ERRNO_FROM_WINERROR CW_GET_ERRNO_FROM_WINERROR #define CW_GET_ERRNO_FROM_WINERROR CW_GET_ERRNO_FROM_WINERROR
#define CW_GET_POSIX_SECURITY_ATTRIBUTE CW_GET_POSIX_SECURITY_ATTRIBUTE #define CW_GET_POSIX_SECURITY_ATTRIBUTE CW_GET_POSIX_SECURITY_ATTRIBUTE