Very strange command-line argument handling of /?

Discussion in 'C Programming' started by marctorrance, Mar 4, 2008.

  1. marctorrance

    marctorrance Guest

    This is not strictly a problem concerning the C language, but I
    figured clc might be the only place to find an answer. It's very
    basic, I'm displaying the contents of the arguments vector:

    int main(int argc, char* argv[])
    {

    /* counters */
    long int i, j;

    /* analyse command-line arguments */
    for (i=1; i < argc; i++) {
    j=0;
    while (argv[j]!='\0') {
    printf("%d %c ",argv[j],argv[j]);
    j++;
    }
    printf("\n");
    }
    }

    I'm on win32, using the latest stable release of gcc, mingw, compiling
    on a FAT32 partition. It seems the whole problem is to do with this
    combination.

    When I execute "program /?" from the command-line it displays "47 /
    99 c". This only happens if I execute the program from the FAT32
    drive on which I compiled it.

    If I copy the program to another drive (e.g. flash drive, NTFS
    partition) it works fine, displaying "47 / 63 ?". On another machine
    it's also fine. If I SUBST a new drive to point to the problem
    directory and run from the SUBSTed drive, it works fine. However, if
    the current directory (i.e. I guess "working directory") is anywhere
    in the original FAT32 partition it displays "47 / 99 c".
    "/?" is the only problem combination I've discovered (e.g. "program
    -?" works OK in all cases), but it doesn't inspire me with a lot of
    confidence.

    Anyone seen this before or know where to look for an answer?

    Thanks.
     
    marctorrance, Mar 4, 2008
    #1
    1. Advertising

  2. In article <>,
    marctorrance <> wrote:
    >This is not strictly a problem concerning the C language, but I
    >figured clc might be the only place to find an answer. It's very
    >basic, I'm displaying the contents of the arguments vector:


    >I'm on win32, using the latest stable release of gcc, mingw, compiling
    >on a FAT32 partition. It seems the whole problem is to do with this
    >combination.


    >When I execute "program /?" from the command-line it displays "47 /
    >99 c". This only happens if I execute the program from the FAT32
    >drive on which I compiled it.
    >
    >If I copy the program to another drive (e.g. flash drive, NTFS
    >partition) it works fine, displaying "47 / 63 ?".


    Possibly you are getting shell pattern matching. /? in some shells
    might expand to any file in the directory / that had a single
    character name. While you are executing under mingw there
    are (if I recall correctly) aliases created for each drive letter
    so /c /d and whatever else appropriate exist to be matched against.
    But execute outside of mingw and the pattern matching might not occur
    (because you are no longer in the shell), and probably those
    other drives do not happen to have single-character file
    (or directory) names immediately in the root of the drive.
    --
    "We may gather out of history a policy, by the comparison and
    application of other men's forepassed miseries with our own like
    errors and ill deservings." -- Sir Walter Raleigh
     
    Walter Roberson, Mar 4, 2008
    #2
    1. Advertising

  3. marctorrance

    marctorrance Guest

    On Mar 4, 6:28 pm, -cnrc.gc.ca (Walter Roberson)
    wrote:
    >
    > Possibly you are getting shell pattern matching. /? in some shells
    > might expand to any file in the directory / that had a single
    > character name.


    Walter you are a genius. I have a directory called "c" on that
    partition. I guess shell pattern matching is something outside my
    control (within the C program), but do correct me if I'm wrong.
     
    marctorrance, Mar 4, 2008
    #3
  4. In article <>,
    marctorrance <> wrote:
    >On Mar 4, 6:28=A0pm, -cnrc.gc.ca (Walter Roberson)
    >wrote:


    >> Possibly you are getting shell pattern matching. /? in some shells
    >> might expand to any file in the directory / that had a single
    >> character name.


    >Walter you are a genius. I have a directory called "c" on that
    >partition. I guess shell pattern matching is something outside my
    >control (within the C program), but do correct me if I'm wrong.


    Try using "/?" as the argument. But of course if it is a Windows
    system, users are going to expect /? without having to quote it.
    Not much that can be done about that :(

    --
    "Is there any thing whereof it may be said, See, this is new? It hath
    been already of old time, which was before us." -- Ecclesiastes
     
    Walter Roberson, Mar 4, 2008
    #4
  5. marctorrance wrote:
    >
    > This is not strictly a problem concerning the C language, but I
    > figured clc might be the only place to find an answer. It's very
    > basic, I'm displaying the contents of the arguments vector:
    >
    > int main(int argc, char* argv[])
    > {
    >
    > /* counters */
    > long int i, j;
    >
    > /* analyse command-line arguments */
    > for (i=1; i < argc; i++) {
    > j=0;
    > while (argv[j]!='\0') {
    > printf("%d %c ",argv[j],argv[j]);
    > j++;
    > }
    > printf("\n");
    > }
    > }
    >
    > I'm on win32, using the latest stable release of gcc, mingw, compiling
    > on a FAT32 partition. It seems the whole problem is to do with this
    > combination.
    >
    > When I execute "program /?" from the command-line it displays "47 /
    > 99 c". This only happens if I execute the program from the FAT32
    > drive on which I compiled it.
    >
    > If I copy the program to another drive (e.g. flash drive, NTFS
    > partition) it works fine, displaying "47 / 63 ?". On another machine
    > it's also fine. If I SUBST a new drive to point to the problem
    > directory and run from the SUBSTed drive, it works fine. However, if
    > the current directory (i.e. I guess "working directory") is anywhere
    > in the original FAT32 partition it displays "47 / 99 c".
    > "/?" is the only problem combination I've discovered (e.g. "program
    > -?" works OK in all cases), but it doesn't inspire me with a lot of
    > confidence.
    >
    > Anyone seen this before or know where to look for an answer?


    Look into whether or not your implementation and/or O/S will
    expand wildcards on the command line.

    For example, on Unix, passing "/?" (without the quotes) on the
    command line will expand to all of the single-character filenames
    in the root directory.

    What happens with "/*" or "/??" (again, without quotes) on your
    system?

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Mar 4, 2008
    #5
  6. marctorrance

    marctorrance Guest

    > Try using "/?" as the argument. But of course if it is a Windows
    > system, users are going to expect /? without having to quote it.

    Yes quotes fixes it - there must be a way around having to do this.

    > Not much that can be done about that :(

    Surely something!

    > Look into whether or not your implementation and/or O/S will
    > expand wildcards on the command line.

    Clearly the combination does expand wildcards - my latest thought is
    there must be a way to turn it off using compiler options, any ideas?

    > What happens with "/*" or "/??" (again, without quotes) on your
    > system?

    Yes, it blows up. Quite amusing really.
     
    marctorrance, Mar 5, 2008
    #6
  7. marctorrance

    Mark Bluemel Guest

    marctorrance wrote:
    >
    > Clearly the combination does expand wildcards - my latest thought is
    > there must be a way to turn it off using compiler options, any ideas?


    Given that the expansion is almost certainly happening at the shell
    (command line interpreter) level, before the program actually gets
    invoked, it seems highly unlikely that anything you do to your program
    will affect this.

    I seem to recall that the Primos environment allowed you to control
    this sort of thing, via non-portable interfaces, but I doubt you'll
    have this option elsewhere.
     
    Mark Bluemel, Mar 5, 2008
    #7
  8. marctorrance

    santosh Guest

    marctorrance wrote:

    >> Try using "/?" as the argument. But of course if it is a Windows
    >> system, users are going to expect /? without having to quote it.

    > Yes quotes fixes it - there must be a way around having to do this.
    >
    >> Not much that can be done about that :(

    > Surely something!
    >
    >> Look into whether or not your implementation and/or O/S will
    >> expand wildcards on the command line.

    > Clearly the combination does expand wildcards - my latest thought is
    > there must be a way to turn it off using compiler options, any ideas?


    <snip>

    This has almost certainly nothing to do with your compiler, but your
    command interpreter. Did you see it's documentation. Most shells have a
    way to turn of wildcard matching, globbing and the like. If it's a
    UNIXish shell try posting to comp.unix.shell where their expertise will
    be able to guide you better than here.
     
    santosh, Mar 5, 2008
    #8
  9. marctorrance

    marctorrance Guest

    On Mar 5, 2:16 pm, santosh <> wrote:
    >
    > This has almost certainly nothing to do with your compiler, but your
    > command interpreter. Did you see it's documentation. Most shells have a
    > way to turn of wildcard matching, globbing and the like. If it's a
    > UNIXish shell try posting to comp.unix.shell where their expertise will
    > be able to guide you better than here.


    It seems it was mingw, or rather Delorie's attempt to make Win32/DOS
    unix-like on the command-line, causing the pattern matching.
    Globbing is off by default in the Win32/DOS shell (if you use "/") but
    it seems that "problem" has a workaround built into mingw by default.
    I suppose preventing the use of "/" helps you to make portable C, but
    I didn't expect to find that behaviour in my simple C program (I guess
    it isn't defined in the standard so the compiler can do what it
    likes).

    To turn it off I followed the one-line instruction at:
    http://www.cygwin.com/ml/cygwin/1999-11/msg00052.html
    add the following line with global scope (above main)
    int _CRT_glob = 0;
     
    marctorrance, Mar 6, 2008
    #9
  10. marctorrance

    santosh Guest

    marctorrance wrote:

    > On Mar 5, 2:16 pm, santosh <> wrote:
    >>
    >> This has almost certainly nothing to do with your compiler, but your
    >> command interpreter. Did you see it's documentation. Most shells have
    >> a way to turn of wildcard matching, globbing and the like. If it's a
    >> UNIXish shell try posting to comp.unix.shell where their expertise
    >> will be able to guide you better than here.

    >
    > It seems it was mingw, or rather Delorie's attempt to make Win32/DOS
    > unix-like on the command-line, causing the pattern matching.


    I don't think DJ Delorie had anything to do with MinGW. His work is
    DJGPP, a DOS port of gcc.

    <http://www.mingw.org/history.shtml>

    > Globbing is off by default in the Win32/DOS shell (if you use "/") but
    > it seems that "problem" has a workaround built into mingw by default.
    > I suppose preventing the use of "/" helps you to make portable C,


    Should it? The '/' character is used as a command options delimiter
    under Windows, and a portable C program has to be able to handle it.

    <snip>
     
    santosh, Mar 7, 2008
    #10
  11. marctorrance

    marctorrance Guest

    On Mar 7, 7:17 am, santosh <> wrote:
    > marctorrance wrote:
    > > On Mar 5, 2:16 pm, santosh <> wrote:

    >
    > I don't think DJ Delorie had anything to do with MinGW. His work is
    > DJGPP, a DOS port of gcc.

    Yes, and here's his workaround, dated 1995:
    http://www.koders.com/c/fid033A3AD820E83FF216891DE55D18ADD6267E2549.aspx

    > > Globbing is off by default in the Win32/DOS shell (if you use "/") but
    > > it seems that "problem" has a workaround built into mingw by default.
    > > I suppose preventing the use of "/" helps you to make portable C,

    >
    > Should it?

    No--but it does, by making simple argv processing blow up on platforms
    where you might sensibly want to use "/".

    > The '/' character is used as a command options delimiter
    > under Windows, and a portable C program has to be able to handle it.

    My point exactly, so why should mingw turn it from a command options
    delimiter into a shell pattern matching switch?
    Seems a bit of an odd thing to do to me, if the win32/dos shell
    handles it differently to unix, then let it.
    Anyway, it's a minor point and all those guys, Delorie, Navia, van der
    Heijden, Peters, and all the others have done a great job. I suppose
    it's just the human element coming through. Navia in particular gets a
    lot of flames for that and he probably shouldn't.
     
    marctorrance, Mar 7, 2008
    #11
  12. On Fri, 7 Mar 2008 01:22:26 -0800 (PST), marctorrance
    <> wrote:

    > On Mar 7, 7:17 am, santosh <> wrote:

    <snip: mingw-on-Windows globbing>
    > > The '/' character is used as a command options delimiter
    > > under Windows, and a portable C program has to be able to handle it.


    > My point exactly, so why should mingw turn it from a command options
    > delimiter into a shell pattern matching switch?


    It doesn't really 'turn it ... into pattern matching'. Rather, (most)
    Unix shells try to glob _all_ unquoted wildcard arguments, and pass
    the results to the program; if a wildcard does not match any file, it
    is left as a wildcard. Then, most programs treat any initial arguments
    (and sometimes others) beginning with - as options/flags. (Yes, this
    means that using a broad pattern like * when there exists in the
    current directory a file whose name begins with - causes spurious
    flags.) An argument beginning with / is treated as data; in the common
    case that an argument is (treated as) a filename, initial slash makes
    it an absolute pathname rather than a relative one.

    In contrast, DOS/Windows command processors pass the whole command
    line to a program, and many programs (not all) treat initial arguments
    beginning with - OR / as options/flags, and then glob only arguments
    identified as filenames (or not at all). Mingw by default emulates the
    Unix way by globbing unquoted arguments. This includes both - and /;
    but, as you discovered, there will always be some / names to match,
    but usually no - names, so that 'accidentally' remains as you wanted.

    > Seems a bit of an odd thing to do to me, if the win32/dos shell
    > handles it differently to unix, then let it.


    This is a longstanding argument. Some people want C programs written
    in DOS/Win to work the DOS/Win native way; some people want C programs
    ported from Unix to continue working. That's why there's the option.

    - formerly david.thompson1 || achar(64) || worldnet.att.net
     
    David Thompson, Mar 24, 2008
    #12
  13. marctorrance

    Joe Wright Guest

    santosh wrote:
    > marctorrance wrote:
    >
    >> On Mar 5, 2:16 pm, santosh <> wrote:
    >>> This has almost certainly nothing to do with your compiler, but your
    >>> command interpreter. Did you see it's documentation. Most shells have
    >>> a way to turn of wildcard matching, globbing and the like. If it's a
    >>> UNIXish shell try posting to comp.unix.shell where their expertise
    >>> will be able to guide you better than here.

    >> It seems it was mingw, or rather Delorie's attempt to make Win32/DOS
    >> unix-like on the command-line, causing the pattern matching.

    >
    > I don't think DJ Delorie had anything to do with MinGW. His work is
    > DJGPP, a DOS port of gcc.
    >
    > <http://www.mingw.org/history.shtml>
    >
    >> Globbing is off by default in the Win32/DOS shell (if you use "/") but
    >> it seems that "problem" has a workaround built into mingw by default.
    >> I suppose preventing the use of "/" helps you to make portable C,

    >
    > Should it? The '/' character is used as a command options delimiter
    > under Windows, and a portable C program has to be able to handle it.
    >
    > <snip>
    >

    Does a portable C program need to know and take care of Windows command
    line options conventions? Why? Of Unix conventions? Why?

    Nothing to do with C really, the command shell is in charge. The '/'
    character is reserved in the Unix shells, sh, ksh, etc. as a directory
    separator and cannot be used (as far as I know) in any other way.

    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
     
    Joe Wright, Mar 25, 2008
    #13
  14. In article <>,
    Joe Wright <> wrote:
    ....
    >Nothing to do with C really, the command shell is in charge. The '/'
    >character is reserved in the Unix shells, sh, ksh, etc. as a directory
    >separator and cannot be used (as far as I know) in any other way.


    There's nothing to stop a Unix program from using the / (on the command
    line) as an option indicator, or in any other way it chooses to.
     
    Kenny McCormack, Mar 25, 2008
    #14
  15. marctorrance

    Kaz Kylheku Guest

    On Mar 4, 11:37 am, marctorrance <> wrote:
    > On Mar 4, 6:28 pm, -cnrc.gc.ca (Walter Roberson)
    > wrote:
    >
    > > Possibly you are getting shell pattern matching. /? in some shells
    > > might expand to any file in the directory / that had a single
    > > character name.

    >
    > Walter you are a genius.  I have a directory called "c" on that
    > partition.


    Do not follow this braindamaged convention. Consider supporting "--
    help" as the help option.

    > I guess shell pattern matching is something outside my
    > control (within the C program), but do correct me if I'm wrong.


    The Windows command interpreter doesn't expand patterns; they are
    passed to the program. The Mingw environment must be arranging for
    that expansion to be done; perhaps it can be turned off.

    Windows command line programs have to explicitly match wildcards. This
    has advantages and disadvantages. And note that certain Unix utilities
    do the same thing. For instance when you run find . -name '*foo',
    it's the
    find program that performs the matching.

    After 15 seconds of Googling I found this advice:

    ``By default compile, if you run a MinGW compiled command-line utility
    and pass it a wildcard argument such as *.c, it acts exactly as a unix
    utility and looks for every file ending in .c in your current file
    directory, replacing the *.c argument with the name of every one of
    those files so that your program never actually sees the *.c. To
    prevent this "globbing," put CRT_noglob.o (in the MinGW library
    directory) at the beginning of your link list when linking. ''

    So if you want to write a proper Windows program according to Windows
    conventions, that is what you should do: handle the globbing in your
    application, and only for those arguments that are file specification.
     
    Kaz Kylheku, Mar 25, 2008
    #15
  16. In article <>,
    Joe Wright <> wrote:

    >Nothing to do with C really, the command shell is in charge. The '/'
    >character is reserved in the Unix shells, sh, ksh, etc. as a directory
    >separator and cannot be used (as far as I know) in any other way.


    $ echo $SHELL
    /bin/ksh
    $ echo $((155/17))
    9

    That's at least one use of / in ksh in which '/' is used a
    different way than as a directory seperator.

    Then there is ksh's vi editting mode:

    /string Search backward through history for a previous command
    containing string. String is terminated by a "RETURN" or
    "NEW LINE". If string is preceded by a ^, the matched
    line must begin with string. If string is null the
    previous string will be used.

    --
    "Man's life is but a jest,
    A dream, a shadow, bubble, air, a vapor at the best."
    -- George Walter Thornbury
     
    Walter Roberson, Mar 25, 2008
    #16
  17. marctorrance

    santosh Guest

    Joe Wright wrote:

    > santosh wrote:
    >> marctorrance wrote:
    >>
    >>> On Mar 5, 2:16 pm, santosh <> wrote:
    >>>> This has almost certainly nothing to do with your compiler, but
    >>>> your command interpreter. Did you see it's documentation. Most
    >>>> shells have a way to turn of wildcard matching, globbing and the
    >>>> like. If it's a UNIXish shell try posting to comp.unix.shell where
    >>>> their expertise will be able to guide you better than here.
    >>> It seems it was mingw, or rather Delorie's attempt to make Win32/DOS
    >>> unix-like on the command-line, causing the pattern matching.

    >>
    >> I don't think DJ Delorie had anything to do with MinGW. His work is
    >> DJGPP, a DOS port of gcc.
    >>
    >> <http://www.mingw.org/history.shtml>
    >>
    >>> Globbing is off by default in the Win32/DOS shell (if you use "/")
    >>> but it seems that "problem" has a workaround built into mingw by
    >>> default. I suppose preventing the use of "/" helps you to make
    >>> portable C,

    >>
    >> Should it? The '/' character is used as a command options delimiter
    >> under Windows, and a portable C program has to be able to handle it.
    >>
    >> <snip>
    >>

    > Does a portable C program need to know and take care of Windows
    > command line options conventions? Why? Of Unix conventions? Why?


    The problem is a portable program can't assume that it is running on a
    particular system. Therefore it might very well be given options
    separated by '/', '-', '--', ' ', or by any other character. The best
    option is of course to follow the conventions of the system under which
    it runs, which means that it must use a generalised command parsing
    code (like GNU getopt) and not hardwire the options delimiter.

    <snip>
     
    santosh, Mar 25, 2008
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Raymond Arthur St. Marie II of III

    very Very VERY dumb Question About The new Set( ) 's

    Raymond Arthur St. Marie II of III, Jul 23, 2003, in forum: Python
    Replies:
    4
    Views:
    518
    Raymond Hettinger
    Jul 27, 2003
  2. shanx__=|;-

    very very very long integer

    shanx__=|;-, Oct 16, 2004, in forum: C Programming
    Replies:
    19
    Views:
    1,718
    Merrill & Michele
    Oct 19, 2004
  3. Abhishek Jha

    very very very long integer

    Abhishek Jha, Oct 16, 2004, in forum: C Programming
    Replies:
    4
    Views:
    467
    jacob navia
    Oct 17, 2004
  4. Peter

    Very very very basic question

    Peter, Feb 8, 2005, in forum: C Programming
    Replies:
    14
    Views:
    542
    Dave Thompson
    Feb 14, 2005
  5. olivier.melcher

    Help running a very very very simple code

    olivier.melcher, May 12, 2008, in forum: Java
    Replies:
    8
    Views:
    2,376
Loading...

Share This Page