Tom Lane wrote:
> It might work to measure time since the start of the whole process, or
> until the timeout target, rather than accumulating adjustments to the
> "remains" count each time through. In other words something like
>
> at start: targettime = time() + specified-timeout
>
> each time we are about to wait: set select timeout to
> targettime - time().
>
> This bounds the error at 1 second which is probably good enough (you
> might want to add 1 to targettime to ensure the error is in the
> conservative direction of not timing out too soon).
>
The attached patch fixes a number of issues related to compiling the client
utilities (libpq.dll and psql.exe) for win32 (missing defines, adjustments to
includes, pedantic casting, non-existent functions) per:
http://developer.postgresql.org/docs/postgres/install-win32.html.
It compiles cleanly under Windows 2000 using Visual Studio .net. Also compiles
clean and passes all regression tests (regular and contrib) under Linux.
In addition to a review by the usual suspects, it would be very desirable for
someone well versed in the peculiarities of win32 to take a look.
If there are no objections, please commit.
Thanks,
Joe
Index: src/backend/libpq/md5.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/backend/libpq/md5.c,v
retrieving revision 1.18
diff -c -r1.18 md5.c
*** src/backend/libpq/md5.c 4 Sep 2002 20:31:19 -0000 1.18
--- src/backend/libpq/md5.c 26 Sep 2002 17:56:11 -0000
***************
*** 26,35 ****
* can be compiled stand-alone.
*/
! #ifndef MD5_ODBC
#include "postgres.h"
#include "libpq/crypt.h"
! #else
#include "md5.h"
#endif
--- 26,44 ----
* can be compiled stand-alone.
*/
! #if ! defined(MD5_ODBC) && ! defined(FRONTEND)
#include "postgres.h"
#include "libpq/crypt.h"
! #endif
!
! #ifdef FRONTEND
! #include "postgres_fe.h"
! #ifndef WIN32
! #include "libpq/crypt.h"
! #endif /* WIN32 */
! #endif /* FRONTEND */
!
! #ifdef MD5_ODBC
#include "md5.h"
#endif
Index: src/bin/psql/command.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/bin/psql/command.c,v
retrieving revision 1.81
diff -c -r1.81 command.c
*** src/bin/psql/command.c 22 Sep 2002 20:57:21 -0000 1.81
--- src/bin/psql/command.c 26 Sep 2002 18:18:17 -0000
***************
*** 23,28 ****
--- 23,29 ----
#include <win32.h>
#include <io.h>
#include <fcntl.h>
+ #include <direct.h>
#endif
#include "libpq-fe.h"
***************
*** 1163,1169 ****
return NULL;
}
! if (i < token_len - 1)
return_val[i + 1] = '\0';
}
--- 1164,1170 ----
return NULL;
}
! if (i < (int) token_len - 1)
return_val[i + 1] = '\0';
}
***************
*** 1240,1246 ****
exit(EXIT_FAILURE);
}
! for (p = source; p - source < len && *p; p += PQmblen(p, pset.encoding))
{
if (esc)
{
--- 1241,1247 ----
exit(EXIT_FAILURE);
}
! for (p = source; p - source < (int) len && *p; p += PQmblen(p, pset.encoding))
{
if (esc)
{
***************
*** 1278,1284 ****
char *end;
l = strtol(p, &end, 0);
! c = l;
p = end - 1;
break;
}
--- 1279,1285 ----
char *end;
l = strtol(p, &end, 0);
! c = (char) l;
p = end - 1;
break;
}
Index: src/bin/psql/common.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/bin/psql/common.c,v
retrieving revision 1.45
diff -c -r1.45 common.c
*** src/bin/psql/common.c 14 Sep 2002 19:46:01 -0000 1.45
--- src/bin/psql/common.c 26 Sep 2002 18:43:31 -0000
***************
*** 11,27 ****
#include <errno.h>
#include <stdarg.h>
- #include <sys/time.h>
#ifndef HAVE_STRDUP
#include <strdup.h>
#endif
#include <signal.h>
#ifndef WIN32
#include <unistd.h> /* for write() */
#include <setjmp.h>
#else
#include <io.h> /* for _write() */
#include <win32.h>
#endif
#include "libpq-fe.h"
--- 11,28 ----
#include <errno.h>
#include <stdarg.h>
#ifndef HAVE_STRDUP
#include <strdup.h>
#endif
#include <signal.h>
#ifndef WIN32
+ #include <sys/time.h>
#include <unistd.h> /* for write() */
#include <setjmp.h>
#else
#include <io.h> /* for _write() */
#include <win32.h>
+ #include <sys/timeb.h> /* for _ftime() */
#endif
#include "libpq-fe.h"
***************
*** 295,303 ****
bool success = false;
PGresult *results;
PGnotify *notify;
struct timeval before,
after;
! struct timezone tz;
if (!pset.db)
{
--- 296,308 ----
bool success = false;
PGresult *results;
PGnotify *notify;
+ #ifndef WIN32
struct timeval before,
after;
! #else
! struct _timeb before,
! after;
! #endif
if (!pset.db)
{
***************
*** 327,337 ****
}
cancelConn = pset.db;
if (pset.timing)
! gettimeofday(&before, &tz);
results = PQexec(pset.db, query);
if (pset.timing)
! gettimeofday(&after, &tz);
if (PQresultStatus(results) == PGRES_COPY_IN)
copy_in_state = true;
/* keep cancel connection for copy out state */
--- 332,352 ----
}
cancelConn = pset.db;
+
+ #ifndef WIN32
+ if (pset.timing)
+ gettimeofday(&before, NULL);
+ results = PQexec(pset.db, query);
+ if (pset.timing)
+ gettimeofday(&after, NULL);
+ #else
if (pset.timing)
! _ftime(&before);
results = PQexec(pset.db, query);
if (pset.timing)
! _ftime(&after);
! #endif
!
if (PQresultStatus(results) == PGRES_COPY_IN)
copy_in_state = true;
/* keep cancel connection for copy out state */
***************
*** 463,470 ****
--- 478,490 ----
/* Possible microtiming output */
if (pset.timing && success)
+ #ifndef WIN32
printf(gettext("Time: %.2f ms\n"),
((after.tv_sec - before.tv_sec) * 1000000.0 + after.tv_usec
- before.tv_usec) / 1000.0);
+ #else
+ printf(gettext("Time: %.2f ms\n"),
+ ((after.time - before.time) * 1000.0 + after.millitm -
+before.millitm));
+ #endif
return success;
}
Index: src/bin/psql/copy.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/bin/psql/copy.c,v
retrieving revision 1.25
diff -c -r1.25 copy.c
*** src/bin/psql/copy.c 22 Sep 2002 20:57:21 -0000 1.25
--- src/bin/psql/copy.c 26 Sep 2002 18:59:11 -0000
***************
*** 28,33 ****
--- 28,35 ----
#ifdef WIN32
#define strcasecmp(x,y) stricmp(x,y)
+ #define __S_ISTYPE(mode, mask) (((mode) & S_IFMT) == (mask))
+ #define S_ISDIR(mode) __S_ISTYPE((mode), S_IFDIR)
#endif
bool copy_in_state;
Index: src/bin/psql/large_obj.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/bin/psql/large_obj.c,v
retrieving revision 1.21
diff -c -r1.21 large_obj.c
*** src/bin/psql/large_obj.c 4 Sep 2002 20:31:36 -0000 1.21
--- src/bin/psql/large_obj.c 26 Sep 2002 19:04:07 -0000
***************
*** 196,202 ****
{
char *cmdbuf;
char *bufptr;
! int slen = strlen(comment_arg);
cmdbuf = malloc(slen * 2 + 256);
if (!cmdbuf)
--- 196,202 ----
{
char *cmdbuf;
char *bufptr;
! size_t slen = strlen(comment_arg);
cmdbuf = malloc(slen * 2 + 256);
if (!cmdbuf)
Index: src/bin/psql/mbprint.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/bin/psql/mbprint.c,v
retrieving revision 1.4
diff -c -r1.4 mbprint.c
*** src/bin/psql/mbprint.c 27 Aug 2002 20:16:48 -0000 1.4
--- src/bin/psql/mbprint.c 26 Sep 2002 20:11:44 -0000
***************
*** 202,208 ****
for (; *pwcs && len > 0; pwcs += l)
{
l = pg_utf_mblen(pwcs);
! if ((len < l) || ((w = ucs_wcwidth(utf2ucs(pwcs))) < 0))
return width;
len -= l;
width += w;
--- 202,208 ----
for (; *pwcs && len > 0; pwcs += l)
{
l = pg_utf_mblen(pwcs);
! if ((len < (size_t) l) || ((w = ucs_wcwidth(utf2ucs(pwcs))) < 0))
return width;
len -= l;
width += w;
Index: src/bin/psql/print.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/bin/psql/print.c,v
retrieving revision 1.31
diff -c -r1.31 print.c
*** src/bin/psql/print.c 1 Sep 2002 23:30:46 -0000 1.31
--- src/bin/psql/print.c 26 Sep 2002 21:10:59 -0000
***************
*** 282,288 ****
{
int tlen;
! if ((tlen = pg_wcswidth((unsigned char *) title, strlen(title))) >=
total_w)
fprintf(fout, "%s\n", title);
else
fprintf(fout, "%-*s%s\n", (int) (total_w - tlen) / 2, "",
title);
--- 282,288 ----
{
int tlen;
! if ((unsigned int) (tlen = pg_wcswidth((unsigned char *) title,
strlen(title))) >= total_w)
fprintf(fout, "%s\n", title);
else
fprintf(fout, "%-*s%s\n", (int) (total_w - tlen) / 2, "",
title);
***************
*** 1184,1191 ****
footers ? (const char *const *) footers : (const char
*const *) (opt->footers),
align, &opt->topt, fout);
! free(headers);
! free(cells);
if (footers)
{
free(footers[0]);
--- 1184,1191 ----
footers ? (const char *const *) footers : (const char
*const *) (opt->footers),
align, &opt->topt, fout);
! free((void *) headers);
! free((void *) cells);
if (footers)
{
free(footers[0]);
Index: src/include/pg_config.h.win32
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/include/pg_config.h.win32,v
retrieving revision 1.7
diff -c -r1.7 pg_config.h.win32
*** src/include/pg_config.h.win32 4 Sep 2002 22:54:18 -0000 1.7
--- src/include/pg_config.h.win32 26 Sep 2002 17:32:07 -0000
***************
*** 16,21 ****
--- 16,23 ----
#define MAXPGPATH 1024
+ #define INDEX_MAX_KEYS 32
+
#define HAVE_ATEXIT
#define HAVE_MEMMOVE
***************
*** 48,53 ****
--- 50,59 ----
#define DLLIMPORT
+ #endif
+
+ #ifndef __CYGWIN__
+ #include <windows.h>
#endif
#endif /* pg_config_h_win32__ */
Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.205
diff -c -r1.205 fe-connect.c
*** src/interfaces/libpq/fe-connect.c 22 Sep 2002 20:57:21 -0000 1.205
--- src/interfaces/libpq/fe-connect.c 26 Sep 2002 00:32:48 -0000
***************
*** 21,27 ****
#include <errno.h>
#include <ctype.h>
#include <time.h>
- #include <unistd.h>
#include "libpq-fe.h"
#include "libpq-int.h"
--- 21,26 ----
***************
*** 1053,1062 ****
{
PostgresPollingStatusType flag = PGRES_POLLING_WRITING;
! struct timeval remains,
! *rp = NULL,
! finish_time,
! start_time;
if (conn == NULL || conn->status == CONNECTION_BAD)
return 0;
--- 1052,1061 ----
{
PostgresPollingStatusType flag = PGRES_POLLING_WRITING;
! time_t finish_time = 0,
! current_time;
! struct timeval remains,
! *rp = NULL;
if (conn == NULL || conn->status == CONNECTION_BAD)
return 0;
***************
*** 1074,1093 ****
}
remains.tv_usec = 0;
rp = &remains;
}
while (rp == NULL || remains.tv_sec > 0 || remains.tv_usec > 0)
{
/*
- * If connecting timeout is set, get current time.
- */
- if (rp != NULL && gettimeofday(&start_time, NULL) == -1)
- {
- conn->status = CONNECTION_BAD;
- return 0;
- }
-
- /*
* Wait, if necessary. Note that the initial state (just after
* PQconnectStart) is to wait for the socket to select for
* writing.
--- 1073,1086 ----
}
remains.tv_usec = 0;
rp = &remains;
+
+ /* calculate the finish time based on start + timeout */
+ finish_time = time((time_t *) NULL) + remains.tv_sec;
}
while (rp == NULL || remains.tv_sec > 0 || remains.tv_usec > 0)
{
/*
* Wait, if necessary. Note that the initial state (just after
* PQconnectStart) is to wait for the socket to select for
* writing.
***************
*** 1128,1153 ****
flag = PQconnectPoll(conn);
/*
! * If connecting timeout is set, calculate remain time.
*/
if (rp != NULL)
{
! if (gettimeofday(&finish_time, NULL) == -1)
{
conn->status = CONNECTION_BAD;
return 0;
}
! if ((finish_time.tv_usec -= start_time.tv_usec) < 0)
! {
! remains.tv_sec++;
! finish_time.tv_usec += 1000000;
! }
! if ((remains.tv_usec -= finish_time.tv_usec) < 0)
! {
! remains.tv_sec--;
! remains.tv_usec += 1000000;
! }
! remains.tv_sec -= finish_time.tv_sec - start_time.tv_sec;
}
}
conn->status = CONNECTION_BAD;
--- 1121,1138 ----
flag = PQconnectPoll(conn);
/*
! * If connecting timeout is set, calculate remaining time.
*/
if (rp != NULL)
{
! if (time(¤t_time) == -1)
{
conn->status = CONNECTION_BAD;
return 0;
}
!
! remains.tv_sec = finish_time - current_time;
! remains.tv_usec = 0;
}
}
conn->status = CONNECTION_BAD;
***************
*** 2946,2951 ****
--- 2931,2937 ----
return NULL;
}
+ #ifndef WIN32
/* If password file is insecure, alert the user and ignore it. */
if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
{
***************
*** 2955,2960 ****
--- 2941,2947 ----
free(pgpassfile);
return NULL;
}
+ #endif
fp = fopen(pgpassfile, "r");
free(pgpassfile);
Index: src/interfaces/libpq/fe-misc.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/interfaces/libpq/fe-misc.c,v
retrieving revision 1.79
diff -c -r1.79 fe-misc.c
*** src/interfaces/libpq/fe-misc.c 4 Sep 2002 20:31:47 -0000 1.79
--- src/interfaces/libpq/fe-misc.c 26 Sep 2002 05:16:52 -0000
***************
*** 150,158 ****
* try to grow the buffer. FIXME: The new size could be
* chosen more intelligently.
*/
! size_t buflen = conn->outCount + nbytes;
! if (buflen > conn->outBufSize)
{
char *newbuf = realloc(conn->outBuffer,
buflen);
--- 150,158 ----
* try to grow the buffer. FIXME: The new size could be
* chosen more intelligently.
*/
! size_t buflen = (size_t) conn->outCount +
nbytes;
! if (buflen > (size_t) conn->outBufSize)
{
char *newbuf = realloc(conn->outBuffer,
buflen);
***************
*** 240,246 ****
int
pqGetnchar(char *s, size_t len, PGconn *conn)
{
! if (len < 0 || len > conn->inEnd - conn->inCursor)
return EOF;
memcpy(s, conn->inBuffer + conn->inCursor, len);
--- 240,246 ----
int
pqGetnchar(char *s, size_t len, PGconn *conn)
{
! if (len < 0 || len > (size_t) (conn->inEnd - conn->inCursor))
return EOF;
memcpy(s, conn->inBuffer + conn->inCursor, len);
Index: src/interfaces/libpq/fe-print.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/interfaces/libpq/fe-print.c,v
retrieving revision 1.46
diff -c -r1.46 fe-print.c
*** src/interfaces/libpq/fe-print.c 29 Aug 2002 07:22:30 -0000 1.46
--- src/interfaces/libpq/fe-print.c 26 Sep 2002 05:08:47 -0000
***************
*** 299,305 ****
(PQntuples(res) == 1) ? "" : "s");
free(fieldMax);
free(fieldNotNum);
! free(fieldNames);
if (usePipe)
{
#ifdef WIN32
--- 299,305 ----
(PQntuples(res) == 1) ? "" : "s");
free(fieldMax);
free(fieldNotNum);
! free((void *) fieldNames);
if (usePipe)
{
#ifdef WIN32
Index: src/interfaces/libpq/libpq-int.h
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/interfaces/libpq/libpq-int.h,v
retrieving revision 1.57
diff -c -r1.57 libpq-int.h
*** src/interfaces/libpq/libpq-int.h 4 Sep 2002 20:31:47 -0000 1.57
--- src/interfaces/libpq/libpq-int.h 25 Sep 2002 21:08:03 -0000
***************
*** 21,28 ****
#define LIBPQ_INT_H
#include <time.h>
- #include <sys/time.h>
#include <sys/types.h>
#if defined(WIN32) && (!defined(ssize_t))
typedef int ssize_t; /* ssize_t doesn't exist in VC (atleast
--- 21,30 ----
#define LIBPQ_INT_H
#include <time.h>
#include <sys/types.h>
+ #ifndef WIN32
+ #include <sys/time.h>
+ #endif
#if defined(WIN32) && (!defined(ssize_t))
typedef int ssize_t; /* ssize_t doesn't exist in VC (atleast
Index: src/interfaces/libpq/libpqdll.def
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/interfaces/libpq/libpqdll.def,v
retrieving revision 1.15
diff -c -r1.15 libpqdll.def
*** src/interfaces/libpq/libpqdll.def 2 Jun 2002 22:36:30 -0000 1.15
--- src/interfaces/libpq/libpqdll.def 26 Sep 2002 20:18:48 -0000
***************
*** 1,5 ****
LIBRARY LIBPQ
- DESCRIPTION "Postgres Client Access Library"
EXPORTS
PQconnectdb @ 1
PQsetdbLogin @ 2
--- 1,4 ----
***************
*** 90,92 ****
--- 89,95 ----
PQfreeNotify @ 87
PQescapeString @ 88
PQescapeBytea @ 89
+ printfPQExpBuffer @ 90
+ appendPQExpBuffer @ 91
+ pg_encoding_to_char @ 92
+ pg_utf_mblen @ 93
Index: src/interfaces/libpq/pqexpbuffer.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/interfaces/libpq/pqexpbuffer.c,v
retrieving revision 1.13
diff -c -r1.13 pqexpbuffer.c
*** src/interfaces/libpq/pqexpbuffer.c 20 Jun 2002 20:29:54 -0000 1.13
--- src/interfaces/libpq/pqexpbuffer.c 26 Sep 2002 05:12:17 -0000
***************
*** 192,198 ****
* actually stored, but at least one returns -1 on failure. Be
* conservative about believing whether the print worked.
*/
! if (nprinted >= 0 && nprinted < avail - 1)
{
/* Success. Note nprinted does not include trailing
null. */
str->len += nprinted;
--- 192,198 ----
* actually stored, but at least one returns -1 on failure. Be
* conservative about believing whether the print worked.
*/
! if (nprinted >= 0 && nprinted < (int) avail - 1)
{
/* Success. Note nprinted does not include trailing
null. */
str->len += nprinted;
***************
*** 240,246 ****
* actually stored, but at least one returns -1 on failure. Be
* conservative about believing whether the print worked.
*/
! if (nprinted >= 0 && nprinted < avail - 1)
{
/* Success. Note nprinted does not include trailing
null. */
str->len += nprinted;
--- 240,246 ----
* actually stored, but at least one returns -1 on failure. Be
* conservative about believing whether the print worked.
*/
! if (nprinted >= 0 && nprinted < (int) avail - 1)
{
/* Success. Note nprinted does not include trailing
null. */
str->len += nprinted;
Index: src/interfaces/libpq/win32.h
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/interfaces/libpq/win32.h,v
retrieving revision 1.19
diff -c -r1.19 win32.h
*** src/interfaces/libpq/win32.h 20 Jul 2002 05:43:31 -0000 1.19
--- src/interfaces/libpq/win32.h 26 Sep 2002 17:32:19 -0000
***************
*** 22,28 ****
/*
* crypt not available (yet)
*/
! #define crypt(a,b) (a)
#undef EAGAIN /* doesn't apply on sockets */
#undef EINTR
--- 22,28 ----
/*
* crypt not available (yet)
*/
! #define crypt(a,b) ((char *) a)
#undef EAGAIN /* doesn't apply on sockets */
#undef EINTR
Index: src/utils/Makefile
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/utils/Makefile,v
retrieving revision 1.14
diff -c -r1.14 Makefile
*** src/utils/Makefile 27 Jul 2002 20:10:05 -0000 1.14
--- src/utils/Makefile 26 Sep 2002 05:34:49 -0000
***************
*** 15,18 ****
all:
clean distclean maintainer-clean:
! rm -f dllinit.o
--- 15,18 ----
all:
clean distclean maintainer-clean:
! rm -f dllinit.o getopt.o
Index: src/utils/getopt.c
===================================================================
RCS file: src/utils/getopt.c
diff -N src/utils/getopt.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- src/utils/getopt.c 26 Nov 2001 19:30:58 -0000
***************
*** 0 ****
--- 1,125 ----
+ /*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+ #if defined(LIBC_SCCS) && !defined(lint)
+ static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
+ #endif /* LIBC_SCCS and not lint */
+
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+
+ int opterr = 1, /* if error message should be
+printed */
+ optind = 1, /* index into parent argv
+vector */
+ optopt, /* character checked for
+validity */
+ optreset; /* reset getopt */
+ char *optarg; /* argument associated with option */
+
+ #define BADCH (int)'?'
+ #define BADARG (int)':'
+ #define EMSG ""
+
+ /*
+ * getopt
+ * Parse argc/argv argument vector.
+ */
+ int
+ getopt(nargc, nargv, ostr)
+ int nargc;
+ char *const * nargv;
+ const char *ostr;
+ {
+ extern char *__progname;
+ static char *place = EMSG; /* option letter processing */
+ char *oli; /* option letter list index */
+
+ if (optreset || !*place)
+ { /* update scanning
+pointer */
+ optreset = 0;
+ if (optind >= nargc || *(place = nargv[optind]) != '-')
+ {
+ place = EMSG;
+ return -1;
+ }
+ if (place[1] && *++place == '-' && place[1] == '\0')
+ { /* found "--" */
+ ++optind;
+ place = EMSG;
+ return -1;
+ }
+ } /* option letter okay?
+*/
+ if ((optopt = (int) *place++) == (int) ':' ||
+ !(oli = strchr(ostr, optopt)))
+ {
+ /*
+ * if the user didn't specify '-' as an option, assume it means
+ * -1.
+ */
+ if (optopt == (int) '-')
+ return -1;
+ if (!*place)
+ ++optind;
+ if (opterr && *ostr != ':')
+ (void) fprintf(stderr,
+ "%s: illegal option -- %c\n", __progname,
+optopt);
+ return BADCH;
+ }
+ if (*++oli != ':')
+ { /* don't need argument
+*/
+ optarg = NULL;
+ if (!*place)
+ ++optind;
+ }
+ else
+ { /* need an argument */
+ if (*place) /* no white space */
+ optarg = place;
+ else if (nargc <= ++optind)
+ { /* no arg */
+ place = EMSG;
+ if (*ostr == ':')
+ return BADARG;
+ if (opterr)
+ (void) fprintf(stderr,
+ "%s: option requires an
+argument -- %c\n",
+ __progname, optopt);
+ return BADCH;
+ }
+ else
+ /* white space */
+ optarg = nargv[optind];
+ place = EMSG;
+ ++optind;
+ }
+ return optopt; /* dump back option letter */
+ }
---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to [EMAIL PROTECTED] so that your
message can get through to the mailing list cleanly