public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* cygwin->msvcrt argv expansion algorithems
@ 1999-12-12 12:33 John R Hanson
  1999-12-12 13:38 ` Chris Faylor
  1999-12-31 13:28 ` John R Hanson
  0 siblings, 2 replies; 8+ messages in thread
From: John R Hanson @ 1999-12-12 12:33 UTC (permalink / raw)
  To: cygwin, cgf

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 9118 bytes --]

Hi Chris

You would know better than I where these need to be slotted
into the cygwin .dll.

--- Cut Here ----------------------------------------------------------
  /* this is an example program for encoding and decoding
     command lines to be used when starting a subprocess
     via CreateProcess 
     compile with
     gcc -oCreateP CreateP.c
  */
#include <windows.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#ifdef __CYGWIN__
#define _flushall() fflush(NULL)
#endif

static char * 
basename (const char *name){
  const char *base = name;
  while (*name)
    if ((*name++ == '/')||(name[-1] == '\\')||(name[-1] == ':'))
      base = name;
  return (char *) base;
}

#define CHR(c) { 		\
  if (buf) { 			\
    if (size + 1 > buf_size) 	\
      return -1; 		\
    buf[size] = (char)c; 	\
  } 				\
  size++; 			\
}

#define CHRS(c,n) { 		\
  if (buf) { 			\
    if (size + (n) > buf_size) 	\
      return -1; 		\
    memset (buf + size, c, n); 	\
  } 				\
  size += n; 			\
}

#define STR(s,n) { 		\
  if (buf) { 			\
    if (size + (n) > buf_size) 	\
      return -1; 		\
    memcpy (buf + size, s, n); 	\
  } 				\
  size += n; 			\
}

/*
·	Arguments are delimited by white space, which is either a space or a tab.
·	A string surrounded by double quotation marks is interpreted as a
single argument, regardless of white space contained within. A quoted
string can be embedded in an argument. Note that the caret (^) is not
recognized as an escape character or delimiter. 
·	A double quotation mark preceded by a backslash, \", is interpreted as
a literal double quotation mark (").
·	Backslashes are interpreted literally, unless they immediately precede
a double quotation mark.
·	If an even number of backslashes is followed by a double quotation
mark, then one backslash (\) is placed in the argv array for every pair
of backslashes (\\), and the double quotation mark (") is interpreted as
a string delimiter.
·	If an odd number of backslashes is followed by a double quotation
mark, then one backslash (\) is placed in the argv array for every pair
of backslashes (\\) and the double quotation mark is interpreted as an
escape sequence by the remaining backslash, causing a literal double
quotation mark (") to be placed in argv. 
*/

static size_t
decode_args (
  char         *buf,
  size_t        buf_size,
  char         *CommandLine,
  char        **argv,
  int          *argc) {

  int  		bs;
  int           copy;
  char         *p;
  int           quote;
  size_t        size = 0;

  *argc = 1;

  p = CommandLine;
  if (argv) *argv++ = buf;

  if (*p++ == '\"'){
    while (*p && *p != '\"') {
      CHR(*p);
      p++;
    }
    if (*p == '\"') p++;
  }
  else{
    CHR(p[-1]);
    while (*p && *p != ' ' && *p != '\t'){
      CHR(*p);
      p++;
    }
  }
  CHR('\0');

  quote = FALSE;
  for(;;) {
    if (*p) while (*p == ' ' || *p == '\t') p++;
    if (!*p) break;
    if (argv) *argv++ = &buf[size];
    ++*argc;
    for (;;) {
      copy = TRUE;
      bs = 0;
      while (*p == '\\') {
        p++; bs++;
      }
      if (*p == '\"') {
        if (!(bs % 2)) {
          if (quote) {
            if (p[1] == '\"') p++;
            else copy = FALSE;
          } 
          else copy = FALSE;
          quote = !quote;
        }
        bs >>= bs;
      }
      CHRS('\\', bs);
      if (!*p || (!quote && (*p == ' ' || *p == '\t'))) break;
      if (copy) CHR(*p);
      p++;
    }
    CHR('\0');
  }
  if (argv) *argv++ = NULL;
  return size;
}

static size_t
encode_args (
  char       *buf,
  size_t      buf_size,
  char      **argv,
  int         argc,
  const char *prog_name) {

  size_t      size = 0;
  const char *src, *p, *base;
  int         quote, bs, shell = 0;

  /* assume MS or cyg runtime */
  base = basename(prog_name);
  if (!strncasecmp(base, "cmd", 3) && (base[3] == '.' || base[3] == '\0'))
    shell = 1; 
  else /* .com extension is required */
    if (!strcasecmp (base, "command.com"))
      shell = 2;
  src = *argv++;
  if (argc) {
    STR (src, strlen (src));
    src = *argv++;
  }
  for (;argc > 1;argc--) {
    CHR (' ');
    quote = FALSE;
    if (!*src) quote = TRUE;
    if (!quote)
      for (p = src;*p;p++)
        if (shell < 2)
          if (*p == ' ' || *p == '\t' || *p == '&' || (*p == '"' && shell == 1)) {
            quote = TRUE;
            break;
          }
    if (quote) CHR ('"');
    bs = 0;
    while (*src) {
      if (*src == '"' && !shell) {
        CHRS ('\\', bs + 1);
        bs = 0;
      }
      else 
        if (*src == '\\' && !shell)
          bs++;
        else
          bs = 0;
      CHR (*src);
      src++;
    }
    if (quote) {
      CHRS ('\\', bs);
      bs = 0;
      CHR ('"');
    }
    src = *argv++;
  }
  CHR ('\0');
  return size;
}
#undef CHR
#undef CHRS
#undef STR

void
get_args(){
  /* Most of this would be in mainCRTStartup normally */
  char fname[MAX_PATH], *buf, **argv, *CommandLine = GetCommandLine();
  int buf_size, argc;

  if (!*CommandLine){
    GetModuleFileName(NULL, fname, MAX_PATH);
    CommandLine = fname;
  }
  printf("%s\n", CommandLine);
  if ((buf_size = decode_args(NULL, 0, CommandLine, (char **)NULL, &argc)) < 0) abort();
  if (!(buf = (char *)argv = (char **)alloca(((argc + 1) * sizeof(char *)) + buf_size))) abort();
  buf += ((argc + 1) * sizeof(char *));
  if ((buf_size = decode_args(buf, buf_size, CommandLine, argv, &argc)) < 0) abort();
  while (*argv) printf("%s ", *argv++);
  printf("\n");
  /* main(argc, argv, __environ) */
  exit(0);
}

HANDLE
exec_it(char **argv, char *fname){
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  size_t buf_size;
  char *p, *path_exec;
  void *buf;
  int WinErr;
  char  out_path[1024] = "PATH=";
  int argc = strlen((char *)argv);

  buf_size = encode_args (NULL, 0, argv, argc, fname);

  if ((buf_size < 0)||(buf_size > 1024 * 32)){
    errno = E2BIG;
    return (HANDLE)-1;
  }

  buf = alloca (buf_size);

  if (buf == NULL) {
    errno = ENOMEM;
    return (HANDLE)-1;
  }

  buf_size = encode_args (buf, buf_size, argv, argc, fname);

  if ((buf_size < 0)||(buf_size > 1024 * 32)){
    errno = E2BIG;
    return (HANDLE)-1;
  }

  /* path must be all '\\' */
  if ((p = path_exec = strdup((const char *)getenv("PATH")))){
    while (*p) if (*p++ == '/') p[-1] = '\\';
    putenv(strcat(out_path, path_exec));
    free(path_exec);
  }

  if (fname == (p = basename(fname))) {
    /* force .exe && search if needed */
    if (!strncasecmp(fname, argv[0], strlen(fname)))
      fname = NULL;
  }
  else {
    p = fname;
    while (*p) if (*p++ == '/') p[-1] = '\\';
  }

  /* console only */
  memset(&si, 0, sizeof (STARTUPINFO));
  si.cb = sizeof(STARTUPINFO);
  si.dwFlags = STARTF_USESTDHANDLES;
  si.hStdInput = (HANDLE)_get_osfhandle(0);
  si.hStdOutput  = (HANDLE)_get_osfhandle(1);
  si.hStdError = (HANDLE)_get_osfhandle(2);

  _flushall();
  if (!CreateProcess(fname, buf, NULL, NULL, TRUE, GetPriorityClass ((HANDLE)-1), NULL, NULL, &si, &pi)){
    if (((WinErr = GetLastError()) > 187) && (WinErr < 203))
      errno = ENOEXEC;
    else{ /* ? */
      errno = GetLastError();
    perror("in CreateP");
    }
  }
  else {
    CloseHandle(pi.hThread);
    return pi.hProcess;
  }
  return (HANDLE)-1;
}

int
main(int argc, char **argv){
  HANDLE waitfor;
  char *command_args[] = {"command.com", "/c", "echo \"this\""};
  char *cmd_args[] =     {"cmd",         "/c", "echo \"this\""};
  char *cmd2_args[] =    {"cmd",         "/c", "echo.&&echo."};
  /* non cygwin */
  char *sh_args[] =      {"sh",          "-c", "echo \\\\\\\"this\\\\\\\""};
  char *sh1_args[] =     {"\"sh\"",          "-c", "echo \\\\\\\"this\\\\\\\""};
  /* cygwin */
  char *bash_args[] =    {"bash",        "-c", "echo \\\\\\\"this\\\\\\\""};

  if (argc == 1) {
    waitfor = exec_it(command_args, "CreateP.exe");
    WaitForSingleObject(waitfor, 0x5000);
    waitfor = exec_it(command_args, "command.com");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(cmd_args, "CreateP.exe");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(cmd_args, "cmd");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(cmd2_args, "CreateP.exe");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(cmd2_args, "cmd");
    WaitForSingleObject(waitfor, 0x5000);
    /* cygwin */
    exec_it(bash_args, "CreateP.exe");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(bash_args, "d:\\bin\\bash.exe");
    WaitForSingleObject(waitfor, 0x5000);
    /* non cygwin */
    exec_it(sh_args, "CreateP.exe");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(sh_args, "d:\\bin\\sh.exe");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(sh1_args, "CreateP.exe");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(sh1_args, "d:\\bin\\sh.exe");
    WaitForSingleObject(waitfor, 0x5000);
  }
  else{
    get_args();
  }
  return 0;
}
__________________________________________
NetZero - Defenders of the Free World
Get your FREE Internet Access and Email at
http://www.netzero.net/download/index.html

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: cygwin->msvcrt argv expansion algorithems
  1999-12-12 12:33 cygwin->msvcrt argv expansion algorithems John R Hanson
@ 1999-12-12 13:38 ` Chris Faylor
  1999-12-12 14:04   ` John R Hanson
  1999-12-31 13:28   ` Chris Faylor
  1999-12-31 13:28 ` John R Hanson
  1 sibling, 2 replies; 8+ messages in thread
From: Chris Faylor @ 1999-12-12 13:38 UTC (permalink / raw)
  To: John R Hanson; +Cc: cygwin

On Sun, Dec 12, 1999 at 07:43:34PM +0000, John R Hanson wrote:
>You would know better than I where these need to be slotted
>into the cygwin .dll.

I guess if I took some time, I could probably figure out what "these"
are.  This seems to have something to do with command line quoting,
obviously.  And, you want to plug it into cygwin somewhere.

But I'm sorry to say that I'm not going to take time to investigate
hundred of lines of code, especially when I have no clear idea what
it's for.

If this is intended to replace one of cygwin's quoting methods, it's
unlikely that I'd consider doing that without an extremely compelling
rationale for doing so.  "It doesn't handle all of the cases that MSVC
does" is *not* a  reason for throwing everything away, btw.

Sorry,
Chris

>--- Cut Here ----------------------------------------------------------
>  /* this is an example program for encoding and decoding
>     command lines to be used when starting a subprocess
>     via CreateProcess 
>     compile with
>     gcc -oCreateP CreateP.c
>  */
>[snip]

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: cygwin->msvcrt argv expansion algorithems
  1999-12-12 13:38 ` Chris Faylor
@ 1999-12-12 14:04   ` John R Hanson
  1999-12-12 17:06     ` Chris Faylor
  1999-12-31 13:28     ` John R Hanson
  1999-12-31 13:28   ` Chris Faylor
  1 sibling, 2 replies; 8+ messages in thread
From: John R Hanson @ 1999-12-12 14:04 UTC (permalink / raw)
  To: cygwin

This is pursuant to the discussion of several months
ago about make and interfacing with msvc/mingw32 binaries.
cygwin is not microsoft compatible regarding command
line quoting , so you asked for patches to fix it.

I know nothing about cygwin so here are the algorithms,
someone who knows about cygwin can figure out the fix.

On Sun, 12 Dec 1999 16:38:31 -0500, you wrote:

>On Sun, Dec 12, 1999 at 07:43:34PM +0000, John R Hanson wrote:
>>You would know better than I where these need to be slotted
>>into the cygwin .dll.
>
>I guess if I took some time, I could probably figure out what "these"
>are.  This seems to have something to do with command line quoting,
>obviously.  And, you want to plug it into cygwin somewhere.
>
>But I'm sorry to say that I'm not going to take time to investigate
>hundred of lines of code, especially when I have no clear idea what
>it's for.
>
>If this is intended to replace one of cygwin's quoting methods, it's
>unlikely that I'd consider doing that without an extremely compelling
>rationale for doing so.  "It doesn't handle all of the cases that MSVC
>does" is *not* a  reason for throwing everything away, btw.
>
>Sorry,
>Chris
>
>>--- Cut Here ----------------------------------------------------------
>>  /* this is an example program for encoding and decoding
>>     command lines to be used when starting a subprocess
>>     via CreateProcess 
>>     compile with
>>     gcc -oCreateP CreateP.c
>>  */
>>[snip]

__________________________________________
NetZero - Defenders of the Free World
Get your FREE Internet Access and Email at
http://www.netzero.net/download/index.html

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: cygwin->msvcrt argv expansion algorithems
  1999-12-12 14:04   ` John R Hanson
@ 1999-12-12 17:06     ` Chris Faylor
  1999-12-31 13:28       ` Chris Faylor
  1999-12-31 13:28     ` John R Hanson
  1 sibling, 1 reply; 8+ messages in thread
From: Chris Faylor @ 1999-12-12 17:06 UTC (permalink / raw)
  To: John R Hanson; +Cc: cygwin

On Sun, Dec 12, 1999 at 09:13:40PM +0000, John R Hanson wrote:
>This is pursuant to the discussion of several months ago about make and
>interfacing with msvc/mingw32 binaries.  cygwin is not microsoft
>compatible regarding command line quoting , so you asked for patches to
>fix it.
>
>I know nothing about cygwin so here are the algorithms, someone who
>knows about cygwin can figure out the fix.

I would guess that most people who know about cygwin would be in the
same state as I.  They probably are not bothered by the quoting problems
that were mentioned in August and have not taken the time to look into
fixing them.  Personally, I don't think that adding another couple of
hundred of lines of code into the mix is going to entice anyone but I
guess we'll see.

cgf

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: cygwin->msvcrt argv expansion algorithems
  1999-12-12 13:38 ` Chris Faylor
  1999-12-12 14:04   ` John R Hanson
@ 1999-12-31 13:28   ` Chris Faylor
  1 sibling, 0 replies; 8+ messages in thread
From: Chris Faylor @ 1999-12-31 13:28 UTC (permalink / raw)
  To: John R Hanson; +Cc: cygwin

On Sun, Dec 12, 1999 at 07:43:34PM +0000, John R Hanson wrote:
>You would know better than I where these need to be slotted
>into the cygwin .dll.

I guess if I took some time, I could probably figure out what "these"
are.  This seems to have something to do with command line quoting,
obviously.  And, you want to plug it into cygwin somewhere.

But I'm sorry to say that I'm not going to take time to investigate
hundred of lines of code, especially when I have no clear idea what
it's for.

If this is intended to replace one of cygwin's quoting methods, it's
unlikely that I'd consider doing that without an extremely compelling
rationale for doing so.  "It doesn't handle all of the cases that MSVC
does" is *not* a  reason for throwing everything away, btw.

Sorry,
Chris

>--- Cut Here ----------------------------------------------------------
>  /* this is an example program for encoding and decoding
>     command lines to be used when starting a subprocess
>     via CreateProcess 
>     compile with
>     gcc -oCreateP CreateP.c
>  */
>[snip]

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: cygwin->msvcrt argv expansion algorithems
  1999-12-12 17:06     ` Chris Faylor
@ 1999-12-31 13:28       ` Chris Faylor
  0 siblings, 0 replies; 8+ messages in thread
From: Chris Faylor @ 1999-12-31 13:28 UTC (permalink / raw)
  To: John R Hanson; +Cc: cygwin

On Sun, Dec 12, 1999 at 09:13:40PM +0000, John R Hanson wrote:
>This is pursuant to the discussion of several months ago about make and
>interfacing with msvc/mingw32 binaries.  cygwin is not microsoft
>compatible regarding command line quoting , so you asked for patches to
>fix it.
>
>I know nothing about cygwin so here are the algorithms, someone who
>knows about cygwin can figure out the fix.

I would guess that most people who know about cygwin would be in the
same state as I.  They probably are not bothered by the quoting problems
that were mentioned in August and have not taken the time to look into
fixing them.  Personally, I don't think that adding another couple of
hundred of lines of code into the mix is going to entice anyone but I
guess we'll see.

cgf

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* cygwin->msvcrt argv expansion algorithems
  1999-12-12 12:33 cygwin->msvcrt argv expansion algorithems John R Hanson
  1999-12-12 13:38 ` Chris Faylor
@ 1999-12-31 13:28 ` John R Hanson
  1 sibling, 0 replies; 8+ messages in thread
From: John R Hanson @ 1999-12-31 13:28 UTC (permalink / raw)
  To: cygwin, cgf

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 9118 bytes --]

Hi Chris

You would know better than I where these need to be slotted
into the cygwin .dll.

--- Cut Here ----------------------------------------------------------
  /* this is an example program for encoding and decoding
     command lines to be used when starting a subprocess
     via CreateProcess 
     compile with
     gcc -oCreateP CreateP.c
  */
#include <windows.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#ifdef __CYGWIN__
#define _flushall() fflush(NULL)
#endif

static char * 
basename (const char *name){
  const char *base = name;
  while (*name)
    if ((*name++ == '/')||(name[-1] == '\\')||(name[-1] == ':'))
      base = name;
  return (char *) base;
}

#define CHR(c) { 		\
  if (buf) { 			\
    if (size + 1 > buf_size) 	\
      return -1; 		\
    buf[size] = (char)c; 	\
  } 				\
  size++; 			\
}

#define CHRS(c,n) { 		\
  if (buf) { 			\
    if (size + (n) > buf_size) 	\
      return -1; 		\
    memset (buf + size, c, n); 	\
  } 				\
  size += n; 			\
}

#define STR(s,n) { 		\
  if (buf) { 			\
    if (size + (n) > buf_size) 	\
      return -1; 		\
    memcpy (buf + size, s, n); 	\
  } 				\
  size += n; 			\
}

/*
·	Arguments are delimited by white space, which is either a space or a tab.
·	A string surrounded by double quotation marks is interpreted as a
single argument, regardless of white space contained within. A quoted
string can be embedded in an argument. Note that the caret (^) is not
recognized as an escape character or delimiter. 
·	A double quotation mark preceded by a backslash, \", is interpreted as
a literal double quotation mark (").
·	Backslashes are interpreted literally, unless they immediately precede
a double quotation mark.
·	If an even number of backslashes is followed by a double quotation
mark, then one backslash (\) is placed in the argv array for every pair
of backslashes (\\), and the double quotation mark (") is interpreted as
a string delimiter.
·	If an odd number of backslashes is followed by a double quotation
mark, then one backslash (\) is placed in the argv array for every pair
of backslashes (\\) and the double quotation mark is interpreted as an
escape sequence by the remaining backslash, causing a literal double
quotation mark (") to be placed in argv. 
*/

static size_t
decode_args (
  char         *buf,
  size_t        buf_size,
  char         *CommandLine,
  char        **argv,
  int          *argc) {

  int  		bs;
  int           copy;
  char         *p;
  int           quote;
  size_t        size = 0;

  *argc = 1;

  p = CommandLine;
  if (argv) *argv++ = buf;

  if (*p++ == '\"'){
    while (*p && *p != '\"') {
      CHR(*p);
      p++;
    }
    if (*p == '\"') p++;
  }
  else{
    CHR(p[-1]);
    while (*p && *p != ' ' && *p != '\t'){
      CHR(*p);
      p++;
    }
  }
  CHR('\0');

  quote = FALSE;
  for(;;) {
    if (*p) while (*p == ' ' || *p == '\t') p++;
    if (!*p) break;
    if (argv) *argv++ = &buf[size];
    ++*argc;
    for (;;) {
      copy = TRUE;
      bs = 0;
      while (*p == '\\') {
        p++; bs++;
      }
      if (*p == '\"') {
        if (!(bs % 2)) {
          if (quote) {
            if (p[1] == '\"') p++;
            else copy = FALSE;
          } 
          else copy = FALSE;
          quote = !quote;
        }
        bs >>= bs;
      }
      CHRS('\\', bs);
      if (!*p || (!quote && (*p == ' ' || *p == '\t'))) break;
      if (copy) CHR(*p);
      p++;
    }
    CHR('\0');
  }
  if (argv) *argv++ = NULL;
  return size;
}

static size_t
encode_args (
  char       *buf,
  size_t      buf_size,
  char      **argv,
  int         argc,
  const char *prog_name) {

  size_t      size = 0;
  const char *src, *p, *base;
  int         quote, bs, shell = 0;

  /* assume MS or cyg runtime */
  base = basename(prog_name);
  if (!strncasecmp(base, "cmd", 3) && (base[3] == '.' || base[3] == '\0'))
    shell = 1; 
  else /* .com extension is required */
    if (!strcasecmp (base, "command.com"))
      shell = 2;
  src = *argv++;
  if (argc) {
    STR (src, strlen (src));
    src = *argv++;
  }
  for (;argc > 1;argc--) {
    CHR (' ');
    quote = FALSE;
    if (!*src) quote = TRUE;
    if (!quote)
      for (p = src;*p;p++)
        if (shell < 2)
          if (*p == ' ' || *p == '\t' || *p == '&' || (*p == '"' && shell == 1)) {
            quote = TRUE;
            break;
          }
    if (quote) CHR ('"');
    bs = 0;
    while (*src) {
      if (*src == '"' && !shell) {
        CHRS ('\\', bs + 1);
        bs = 0;
      }
      else 
        if (*src == '\\' && !shell)
          bs++;
        else
          bs = 0;
      CHR (*src);
      src++;
    }
    if (quote) {
      CHRS ('\\', bs);
      bs = 0;
      CHR ('"');
    }
    src = *argv++;
  }
  CHR ('\0');
  return size;
}
#undef CHR
#undef CHRS
#undef STR

void
get_args(){
  /* Most of this would be in mainCRTStartup normally */
  char fname[MAX_PATH], *buf, **argv, *CommandLine = GetCommandLine();
  int buf_size, argc;

  if (!*CommandLine){
    GetModuleFileName(NULL, fname, MAX_PATH);
    CommandLine = fname;
  }
  printf("%s\n", CommandLine);
  if ((buf_size = decode_args(NULL, 0, CommandLine, (char **)NULL, &argc)) < 0) abort();
  if (!(buf = (char *)argv = (char **)alloca(((argc + 1) * sizeof(char *)) + buf_size))) abort();
  buf += ((argc + 1) * sizeof(char *));
  if ((buf_size = decode_args(buf, buf_size, CommandLine, argv, &argc)) < 0) abort();
  while (*argv) printf("%s ", *argv++);
  printf("\n");
  /* main(argc, argv, __environ) */
  exit(0);
}

HANDLE
exec_it(char **argv, char *fname){
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  size_t buf_size;
  char *p, *path_exec;
  void *buf;
  int WinErr;
  char  out_path[1024] = "PATH=";
  int argc = strlen((char *)argv);

  buf_size = encode_args (NULL, 0, argv, argc, fname);

  if ((buf_size < 0)||(buf_size > 1024 * 32)){
    errno = E2BIG;
    return (HANDLE)-1;
  }

  buf = alloca (buf_size);

  if (buf == NULL) {
    errno = ENOMEM;
    return (HANDLE)-1;
  }

  buf_size = encode_args (buf, buf_size, argv, argc, fname);

  if ((buf_size < 0)||(buf_size > 1024 * 32)){
    errno = E2BIG;
    return (HANDLE)-1;
  }

  /* path must be all '\\' */
  if ((p = path_exec = strdup((const char *)getenv("PATH")))){
    while (*p) if (*p++ == '/') p[-1] = '\\';
    putenv(strcat(out_path, path_exec));
    free(path_exec);
  }

  if (fname == (p = basename(fname))) {
    /* force .exe && search if needed */
    if (!strncasecmp(fname, argv[0], strlen(fname)))
      fname = NULL;
  }
  else {
    p = fname;
    while (*p) if (*p++ == '/') p[-1] = '\\';
  }

  /* console only */
  memset(&si, 0, sizeof (STARTUPINFO));
  si.cb = sizeof(STARTUPINFO);
  si.dwFlags = STARTF_USESTDHANDLES;
  si.hStdInput = (HANDLE)_get_osfhandle(0);
  si.hStdOutput  = (HANDLE)_get_osfhandle(1);
  si.hStdError = (HANDLE)_get_osfhandle(2);

  _flushall();
  if (!CreateProcess(fname, buf, NULL, NULL, TRUE, GetPriorityClass ((HANDLE)-1), NULL, NULL, &si, &pi)){
    if (((WinErr = GetLastError()) > 187) && (WinErr < 203))
      errno = ENOEXEC;
    else{ /* ? */
      errno = GetLastError();
    perror("in CreateP");
    }
  }
  else {
    CloseHandle(pi.hThread);
    return pi.hProcess;
  }
  return (HANDLE)-1;
}

int
main(int argc, char **argv){
  HANDLE waitfor;
  char *command_args[] = {"command.com", "/c", "echo \"this\""};
  char *cmd_args[] =     {"cmd",         "/c", "echo \"this\""};
  char *cmd2_args[] =    {"cmd",         "/c", "echo.&&echo."};
  /* non cygwin */
  char *sh_args[] =      {"sh",          "-c", "echo \\\\\\\"this\\\\\\\""};
  char *sh1_args[] =     {"\"sh\"",          "-c", "echo \\\\\\\"this\\\\\\\""};
  /* cygwin */
  char *bash_args[] =    {"bash",        "-c", "echo \\\\\\\"this\\\\\\\""};

  if (argc == 1) {
    waitfor = exec_it(command_args, "CreateP.exe");
    WaitForSingleObject(waitfor, 0x5000);
    waitfor = exec_it(command_args, "command.com");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(cmd_args, "CreateP.exe");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(cmd_args, "cmd");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(cmd2_args, "CreateP.exe");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(cmd2_args, "cmd");
    WaitForSingleObject(waitfor, 0x5000);
    /* cygwin */
    exec_it(bash_args, "CreateP.exe");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(bash_args, "d:\\bin\\bash.exe");
    WaitForSingleObject(waitfor, 0x5000);
    /* non cygwin */
    exec_it(sh_args, "CreateP.exe");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(sh_args, "d:\\bin\\sh.exe");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(sh1_args, "CreateP.exe");
    WaitForSingleObject(waitfor, 0x5000);
    exec_it(sh1_args, "d:\\bin\\sh.exe");
    WaitForSingleObject(waitfor, 0x5000);
  }
  else{
    get_args();
  }
  return 0;
}
__________________________________________
NetZero - Defenders of the Free World
Get your FREE Internet Access and Email at
http://www.netzero.net/download/index.html

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: cygwin->msvcrt argv expansion algorithems
  1999-12-12 14:04   ` John R Hanson
  1999-12-12 17:06     ` Chris Faylor
@ 1999-12-31 13:28     ` John R Hanson
  1 sibling, 0 replies; 8+ messages in thread
From: John R Hanson @ 1999-12-31 13:28 UTC (permalink / raw)
  To: cygwin

This is pursuant to the discussion of several months
ago about make and interfacing with msvc/mingw32 binaries.
cygwin is not microsoft compatible regarding command
line quoting , so you asked for patches to fix it.

I know nothing about cygwin so here are the algorithms,
someone who knows about cygwin can figure out the fix.

On Sun, 12 Dec 1999 16:38:31 -0500, you wrote:

>On Sun, Dec 12, 1999 at 07:43:34PM +0000, John R Hanson wrote:
>>You would know better than I where these need to be slotted
>>into the cygwin .dll.
>
>I guess if I took some time, I could probably figure out what "these"
>are.  This seems to have something to do with command line quoting,
>obviously.  And, you want to plug it into cygwin somewhere.
>
>But I'm sorry to say that I'm not going to take time to investigate
>hundred of lines of code, especially when I have no clear idea what
>it's for.
>
>If this is intended to replace one of cygwin's quoting methods, it's
>unlikely that I'd consider doing that without an extremely compelling
>rationale for doing so.  "It doesn't handle all of the cases that MSVC
>does" is *not* a  reason for throwing everything away, btw.
>
>Sorry,
>Chris
>
>>--- Cut Here ----------------------------------------------------------
>>  /* this is an example program for encoding and decoding
>>     command lines to be used when starting a subprocess
>>     via CreateProcess 
>>     compile with
>>     gcc -oCreateP CreateP.c
>>  */
>>[snip]

__________________________________________
NetZero - Defenders of the Free World
Get your FREE Internet Access and Email at
http://www.netzero.net/download/index.html

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~1999-12-31 13:28 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-12-12 12:33 cygwin->msvcrt argv expansion algorithems John R Hanson
1999-12-12 13:38 ` Chris Faylor
1999-12-12 14:04   ` John R Hanson
1999-12-12 17:06     ` Chris Faylor
1999-12-31 13:28       ` Chris Faylor
1999-12-31 13:28     ` John R Hanson
1999-12-31 13:28   ` Chris Faylor
1999-12-31 13:28 ` John R Hanson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).