X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_50,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: sourceware.org Message-ID: <4A348A2D.5030302@cwilson.fastmail.fm> Date: Sun, 14 Jun 2009 01:27:09 -0400 From: Charles Wilson User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.21) Gecko/20090302 Thunderbird/2.0.0.21 Mnenhy/0.7.6.666 MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: Re: [BUG 1.7 getopt_long() and recv()] has problem for tftp-hpa-5.0 on cygwin-1.7/win2003 References: <675149 DOT 63397 DOT qm AT web110509 DOT mail DOT gq1 DOT yahoo DOT com> In-Reply-To: <675149.63397.qm@web110509.mail.gq1.yahoo.com> Content-Type: multipart/mixed; boundary="------------040509020303040205060406" Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com --------------040509020303040205060406 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Xiaoqiang Zheng wrote: > to make the 2 BUGs more clear: > > * in the while loop of processing options with '-' using > getopt_long(): > > $ tftpd/tftpd -u SYSTEM -L -vvvv -p -c -s /var/log > > 1. it seems the '- '(-u SYSTEM) argument pairs that pass > the second argument as value have the value lost and the variable get > null value. the '-'(-L -p -c -s; -vvvv is a special one) type > arguments that set some flag seems work well. Here's your problem: gcc tftp.o main.o ../common/libcommon.a -liberty /home/Administrator/tftp-hpa-5.0/lib/libxtra.a -o tftp.exe you're linking against libiberty. You're using the getopt functions from libiberty, which are locally bound to the optind variable inside the -liberty library. However, main.c probably #included getopt.h, which on cygwin has declspec(dllimport) declarations for optind -- so, main.o is actually linking to "__imp__optind", a redirection pointer to the optind variable inside cygwin1.dll. Therefore, when your main.o code tries to access optind, it "sees" the one in cygwin1.dll, which is never incremented past one. When you call getopt/getopt_long, you're calling the implementation in libiberty (which manipulates the liberty's version of the optind variable). The solution to this problem is to either 1) don't link to libiberty, or at least, insure that -lcygwin precedes -liberty on the link line, OR 2) do NOT include getopt.h or unistd.h, and instead force to declare all the relevant functions and variables consistent with the versions in -liberty (that is, without declspec(dllimport) decorations). Try the attached getopt_decls.h file from checkx-0.2.0. unchanged, it implements option #1 (with a little help from the Makefile). However, change the #ifdef and it implements #2. -- Chuck --------------040509020303040205060406 Content-Type: text/plain; name="getopt_decls.h" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="getopt_decls.h" /* * Copyright (c) 2006 Charles S. Wilson * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #ifndef GETOPT_DECLS_H #define GETOPT_DECLS_H #if HAVE_CONFIG_H # include #endif /* So this is ONE way... */ #if 0 /* because we're linking against libiberty (for buildargv etc), we are ALSO forced to get getopt from it and NOT from cygwin. If we include getopt.h (or unistd.h), then we'd use declspec(dllimport) variables optind, optopt, and optarg -- but thanks to static linkage, we're using libiberty's getopt() and getopt_long. libiberty's functions use static versions of optind, optopt, and optarg, NOT the declspec ones. So, to make sure that both we and libiberty are talking about the same extern variables: (1) do NOT #include unistd.h or getopt.h !!! (2) define all the stuff from getopt.h right here. */ extern int opterr; extern int optind; extern int optopt; extern int optreset; extern char *optarg; int getopt (int, char * const *, const char *); struct option { const char *name; int has_arg; int *flag; int val; }; int getopt_long (int, char *const *, const char *, const struct option *, int *); int getopt_long_only (int, char *const *, const char *, const struct option *, int *); #define no_argument 0 #define required_argument 1 #define optional_argument 2 #else /* The other way is to go ahead and #include getopt.h, but force linking to the cygwin version of getopt: gcc -o foo.exe foo.o -lcygwin -liberty Which turns into the linker command .... -o foo.exe foo.o -lcygwin -liberty -lgcc -lcygwin ... with 2 -lcygwin. It looks odd, but it's okay. */ # if HAVE_GETOPT_H # include # endif #endif #endif --------------040509020303040205060406 Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --------------040509020303040205060406--