Very strange command-line argument handling of /?

M

marctorrance

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.
 
W

Walter Roberson

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.
 
M

marctorrance

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.
 
W

Walter Roberson

On Mar 4, 6:28=A0pm, (e-mail address removed)-cnrc.gc.ca (Walter Roberson)
wrote:
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 :(
 
K

Kenneth Brody

marctorrance said:
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:[email protected]>
 
M

marctorrance

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.
 
M

Mark Bluemel

marctorrance said:
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.
 
S

santosh

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

Surely something!

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.
 
M

marctorrance

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;
 
S

santosh

marctorrance said:
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.

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>
 
M

marctorrance

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
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.
 
D

David Thompson

On Mar 7, 7:17 am, santosh <[email protected]> wrote:
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
 
J

Joe Wright

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



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.
 
K

Kenny McCormack

Joe Wright said:
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.
 
K

Kaz Kylheku

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.
 
W

Walter Roberson

Joe Wright said:
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.
 
S

santosh

Joe said:
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>
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top