mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-20 16:01:10 +08:00
import winsup-2000-02-17 snapshot
This commit is contained in:
parent
4415a7ef3e
commit
369d8a8fd5
76
winsup/cygwin/autoload.h
Normal file
76
winsup/cygwin/autoload.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* autoload.h: Define functions for auto-loading symbols from a DLL.
|
||||
|
||||
Copyright 1999 Cygnus Solutions.
|
||||
|
||||
Written by Christopher Faylor <cgf@cygnus.com>
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#define LoadDLLinitfunc(dllname) \
|
||||
HANDLE NO_COPY dllname ## _handle = NULL; \
|
||||
static int dllname ## _init () __asm__ (#dllname "_init") __attribute__ ((unused)); \
|
||||
static int dllname ## _init ()
|
||||
|
||||
#define LoadDLLinitnow(dllname) \
|
||||
({__asm__ ("movl $cygwin_dll_func_load, " #dllname "_init_holder"); dllname##_init ();})
|
||||
|
||||
#define _LoadDLLinitnow(dllname) \
|
||||
__asm__ ("movl $cygwin_dll_func_load, " #dllname "_init_holder"); \
|
||||
__asm__ ("call " #dllname "_init"); \
|
||||
|
||||
#define LoadDLLinit(dllname) \
|
||||
__asm__ (".section .data_cygwin_nocopy,\"w\""); \
|
||||
__asm__ (#dllname "_init_holder: .long " #dllname "_init_and_load"); \
|
||||
__asm__ (".text"); \
|
||||
__asm__ (#dllname "_init_and_load:"); \
|
||||
_LoadDLLinitnow (dllname); \
|
||||
__asm__ ("jmp cygwin_dll_func_load");
|
||||
|
||||
|
||||
/* Macro for defining "auto-load" functions.
|
||||
* Note that this is self-modifying code *gasp*.
|
||||
* The first invocation of a routine will trigger the loading of
|
||||
* the DLL. This will then be followed by the discovery of
|
||||
* the procedure's entry point, which is placed into the location
|
||||
* pointed to by the stack pointer. This code then changes
|
||||
* the "call" operand which invoked it to a "jmp" which will
|
||||
* transfer directly to the DLL function on the next invocation.
|
||||
*
|
||||
* Subsequent calls to routines whose transfer address has not been
|
||||
* determined will skip the "load the dll" step, starting at the
|
||||
* "discovery of the DLL" step.
|
||||
*
|
||||
* So, immediately following the the call to one of the above routines
|
||||
* we have:
|
||||
* foojmp (4 bytes) Pointer to a word containing the routine used
|
||||
* to eventually invokethe function. Initially
|
||||
* points to an init function which loads the
|
||||
* DLL, gets the processes load address,
|
||||
* changes the contents here to point to the
|
||||
* function address, and changes the call *(%eax)
|
||||
* to a jmp %eax. If the initialization has been
|
||||
* done, only the load part is done.
|
||||
* DLL handle (4 bytes) The handle to use when loading the DLL.
|
||||
* func name (n bytes) asciz string containing the name of the function
|
||||
* to be loaded.
|
||||
*/
|
||||
|
||||
#define LoadDLLfunc(name, mangled, dllname) \
|
||||
__asm__ (".section .data_cygwin_nocopy,\"w\""); \
|
||||
__asm__ (".global _" #mangled); \
|
||||
__asm__ (".global _win32_" #mangled); \
|
||||
__asm__ (".align 8"); \
|
||||
__asm__ ("_" #mangled ":"); \
|
||||
__asm__ ("_win32_" #mangled ":"); \
|
||||
__asm__ ("movl (" #name "jump),%eax"); \
|
||||
__asm__ ("call *(%eax)"); \
|
||||
__asm__ (#name "jump: .long " #dllname "_init_holder"); \
|
||||
__asm__ (" .long _" #dllname "_handle"); \
|
||||
__asm__ (".asciz \"" #name "\""); \
|
||||
__asm__ (".text");
|
||||
|
||||
extern "C" void cygwin_dll_func_load () __asm__ ("cygwin_dll_func_load");
|
50
winsup/cygwin/cygrun.c
Normal file
50
winsup/cygwin/cygrun.c
Normal file
@ -0,0 +1,50 @@
|
||||
/* cygrun.c: testsuite support program
|
||||
|
||||
Copyright 1999 Cygnus Solutions.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
/* This program is intended to be used only by the testsuite. It runs
|
||||
programs without using the cygwin api, so that the just-built dll
|
||||
can be tested without interference from the currently installed
|
||||
dll. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
STARTUPINFO sa;
|
||||
PROCESS_INFORMATION pi;
|
||||
DWORD ec = 1;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: cygrun [program]\n");
|
||||
exit (0);
|
||||
}
|
||||
|
||||
setenv("CYGWIN_TESTING", "1");
|
||||
SetEnvironmentVariable("CYGWIN_TESTING", "1");
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
if (!CreateProcess(0, argv[1], 0, 0, 1, 0, 0, 0, &sa, &pi))
|
||||
{
|
||||
fprintf(stderr, "CreateProcess %s failed\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
|
||||
GetExitCodeProcess(pi.hProcess, &ec);
|
||||
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
return ec;
|
||||
}
|
17
winsup/cygwin/dll_entry.cc
Normal file
17
winsup/cygwin/dll_entry.cc
Normal file
@ -0,0 +1,17 @@
|
||||
/* dll_entry.cc: Provide the default user DLL linker entry point.
|
||||
|
||||
Copyright 1998, 2000 Cygnus Solutions.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
/* Here we simply instantiate the DECLARE_CYGWIN_DLL to define the
|
||||
linker entry point, __cygwin_dll_entry@12, which in turn calls
|
||||
_DllMain@12 to do user-specific initialization, if any. There is a
|
||||
default DllMain stub in the library if there is no user supplied
|
||||
one. */
|
||||
|
||||
#include "cygwin/cygwin_dll.h"
|
||||
|
||||
DECLARE_CYGWIN_DLL (DllMain);
|
42
winsup/cygwin/dll_main.cc
Normal file
42
winsup/cygwin/dll_main.cc
Normal file
@ -0,0 +1,42 @@
|
||||
/* dll_main.cc: Provide the DllMain stub that the user can override.
|
||||
|
||||
Copyright 1998, 2000 Cygnus Solutions.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <stdio.h>
|
||||
|
||||
extern "C"
|
||||
BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason,
|
||||
LPVOID reserved /* Not used. */ );
|
||||
|
||||
BOOL APIENTRY
|
||||
DllMain (
|
||||
HINSTANCE hInst /* Library instance handle. */ ,
|
||||
DWORD reason /* Reason this function is being called. */ ,
|
||||
LPVOID reserved /* Not used. */ )
|
||||
{
|
||||
switch (reason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
50
winsup/cygwin/external.h
Normal file
50
winsup/cygwin/external.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* external.h: interface to Cygwin internals from external programs.
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CW_LOCK_PINFO,
|
||||
CW_UNLOCK_PINFO,
|
||||
CW_GETTHREADNAME,
|
||||
CW_GETPINFO,
|
||||
CW_SETPINFO,
|
||||
CW_SETTHREADNAME,
|
||||
CW_GETVERSIONINFO,
|
||||
CW_READ_V1_MOUNT_TABLES
|
||||
} cygwin_getinfo_types;
|
||||
|
||||
struct external_pinfo
|
||||
{
|
||||
pid_t pid;
|
||||
pid_t ppid;
|
||||
HANDLE hProcess;
|
||||
DWORD dwProcessId, dwSpawnedProcessId;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
pid_t pgid;
|
||||
pid_t sid;
|
||||
int ctty;
|
||||
mode_t umask;
|
||||
|
||||
long start_time;
|
||||
struct rusage rusage_self;
|
||||
struct rusage rusage_children;
|
||||
|
||||
char progname[MAX_PATH];
|
||||
|
||||
DWORD strace_mask;
|
||||
HANDLE strace_file;
|
||||
|
||||
DWORD process_state;
|
||||
};
|
||||
|
||||
extern "C" DWORD cygwin_internal (cygwin_getinfo_types, ...);
|
||||
|
||||
#define CW_NEXTPID 0x80000000 // or with pid to get next one
|
1
winsup/cygwin/include/cygwin/ip.h
Normal file
1
winsup/cygwin/include/cygwin/ip.h
Normal file
@ -0,0 +1 @@
|
||||
/* ip.h */
|
64
winsup/cygwin/include/rapi.h
Normal file
64
winsup/cygwin/include/rapi.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
rapi.h - main header file for the RAPI API
|
||||
|
||||
Copyright 1999 Cygnus Solutions.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details.
|
||||
*/
|
||||
|
||||
#ifndef _RAPI_H
|
||||
#define _RAPI_H
|
||||
|
||||
typedef struct IRAPIStream
|
||||
{
|
||||
struct IRAPIStreamVtbl * lpVtbl;
|
||||
} IRAPIStream;
|
||||
|
||||
typedef struct IRAPIStreamVtbl IRAPIStreamVtbl;
|
||||
|
||||
typedef enum tagRAPISTREAMFLAG
|
||||
{
|
||||
STREAM_TIMEOUT_READ
|
||||
} RAPISTREAMFLAG;
|
||||
|
||||
struct IRAPIStreamVtbl
|
||||
{
|
||||
HRESULT (__stdcall * SetRapiStat)( IRAPIStream * This, RAPISTREAMFLAG Flag, DWORD dwValue) ;
|
||||
HRESULT (__stdcall * GetRapiStat)( IRAPIStream * This, RAPISTREAMFLAG Flag, DWORD *pdwValue) ;
|
||||
};
|
||||
|
||||
// RAPI extension on Windows CE (e.g., MyFunctionFOO) called via CeRapiInvoke should be declared as:
|
||||
// EXTERN_C RAPIEXT MyFunctionFOO;
|
||||
typedef HRESULT (STDAPICALLTYPE RAPIEXT)(
|
||||
DWORD cbInput, // [IN]
|
||||
BYTE *pInput, // [IN]
|
||||
DWORD *pcbOutput, // [OUT]
|
||||
BYTE **ppOutput, // [OUT]
|
||||
IRAPIStream *pIRAPIStream // [IN]
|
||||
);
|
||||
|
||||
typedef struct _RAPIINIT
|
||||
{
|
||||
DWORD cbSize;
|
||||
HANDLE heRapiInit;
|
||||
HRESULT hrRapiInit;
|
||||
} RAPIINIT;
|
||||
|
||||
STDAPI CeRapiInit();
|
||||
STDAPI CeRapiInitEx(RAPIINIT*);
|
||||
STDAPI_(BOOL) CeCreateProcess(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES,
|
||||
BOOL, DWORD, LPVOID, LPWSTR, LPSTARTUPINFO, LPPROCESS_INFORMATION);
|
||||
STDAPI CeRapiUninit();
|
||||
|
||||
STDAPI_(BOOL) CeWriteFile(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
|
||||
STDAPI_(HANDLE) CeCreateFile(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
|
||||
STDAPI_(BOOL) CeCreateDirectory(LPCWSTR, LPSECURITY_ATTRIBUTES);
|
||||
STDAPI_(DWORD) CeGetLastError(void);
|
||||
STDAPI_(BOOL) CeGetFileTime(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME);
|
||||
STDAPI_(BOOL) CeCloseHandle(HANDLE);
|
||||
|
||||
#endif /* _RAPI_H */
|
27
winsup/cygwin/include/wchar.h
Normal file
27
winsup/cygwin/include/wchar.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* wchar.h
|
||||
|
||||
Copyright 1998 Cygnus Solutions
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#ifndef _WCHAR_H
|
||||
#define _WCHAR_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/* Get wchar_t from <stddef.h>. */
|
||||
#define __need_wchar_t
|
||||
#include <stddef.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int wcscmp (wchar_t *__s1, wchar_t *__s2);
|
||||
int wcslen (wchar_t *__s1);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _WCHAR_H */
|
390
winsup/cygwin/libc/getopt.c
Normal file
390
winsup/cygwin/libc/getopt.c
Normal file
@ -0,0 +1,390 @@
|
||||
/*
|
||||
* Copyright (c) 1987, 1993, 1994, 1996
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "getopt.h"
|
||||
|
||||
int opterr = 1; /* if error message should be printed */
|
||||
int optind = 1; /* index into parent argv vector */
|
||||
int optopt; /* character checked for validity */
|
||||
int optreset; /* reset getopt */
|
||||
char *optarg; /* argument associated with option */
|
||||
|
||||
static char * __progname (char *);
|
||||
int getopt_internal (int, char * const *, const char *);
|
||||
|
||||
static char * __progname(nargv0)
|
||||
char * nargv0;
|
||||
{
|
||||
char * tmp = strrchr(nargv0, '/');
|
||||
if (tmp) tmp++; else tmp = nargv0;
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
#define BADCH (int)'?'
|
||||
#define BADARG (int)':'
|
||||
#define EMSG ""
|
||||
|
||||
/*
|
||||
* getopt --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt_internal(nargc, nargv, ostr)
|
||||
int nargc;
|
||||
char * const *nargv;
|
||||
const char *ostr;
|
||||
{
|
||||
static const 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 == '-') { /* found "--" */
|
||||
/* ++optind; */
|
||||
place = EMSG;
|
||||
return (-2);
|
||||
}
|
||||
} /* 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(nargv[0]), optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
if (*++oli != ':') { /* don't need argument */
|
||||
optarg = NULL;
|
||||
if (!*place)
|
||||
++optind;
|
||||
} else { /* need an argument */
|
||||
if (*place) /* no white space */
|
||||
optarg = (char *)place;
|
||||
else if (nargc <= ++optind) { /* no arg */
|
||||
place = EMSG;
|
||||
if ((opterr) && (*ostr != ':'))
|
||||
(void)fprintf(stderr,
|
||||
"%s: option requires an argument -- %c\n",
|
||||
__progname(nargv[0]), optopt);
|
||||
return (BADARG);
|
||||
} else /* white space */
|
||||
optarg = nargv[optind];
|
||||
place = EMSG;
|
||||
++optind;
|
||||
}
|
||||
return (optopt); /* dump back option letter */
|
||||
}
|
||||
|
||||
/*
|
||||
* getopt --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt(nargc, nargv, ostr)
|
||||
int nargc;
|
||||
char * const *nargv;
|
||||
const char *ostr;
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ((retval = getopt_internal(nargc, nargv, ostr)) == -2) {
|
||||
retval = -1;
|
||||
++optind;
|
||||
}
|
||||
return(retval);
|
||||
}
|
||||
|
||||
/*
|
||||
* getopt_long --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt_long(nargc, nargv, options, long_options, index)
|
||||
int nargc;
|
||||
char ** nargv;
|
||||
char * options;
|
||||
struct option * long_options;
|
||||
int * index;
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ((retval = getopt_internal(nargc, nargv, options)) == -2) {
|
||||
char *current_argv = nargv[optind++] + 2, *has_equal;
|
||||
int i, current_argv_len, match = -1;
|
||||
|
||||
if (*current_argv == '\0') {
|
||||
return(-1);
|
||||
}
|
||||
if ((has_equal = strchr(current_argv, '='))) {
|
||||
current_argv_len = has_equal - current_argv;
|
||||
has_equal++;
|
||||
} else
|
||||
current_argv_len = strlen(current_argv);
|
||||
|
||||
for (i = 0; long_options[i].name; i++) {
|
||||
if (strncmp(current_argv, long_options[i].name, current_argv_len))
|
||||
continue;
|
||||
|
||||
if (strlen(long_options[i].name) == current_argv_len) {
|
||||
match = i;
|
||||
break;
|
||||
}
|
||||
if (match == -1)
|
||||
match = i;
|
||||
}
|
||||
if (match != -1) {
|
||||
if (long_options[match].has_arg) {
|
||||
if (has_equal)
|
||||
optarg = has_equal;
|
||||
else
|
||||
optarg = nargv[optind++];
|
||||
}
|
||||
if ((long_options[match].has_arg == 1) && (optarg == NULL)) {
|
||||
/* Missing option, leading : indecates no error */
|
||||
if ((opterr) && (*options != ':'))
|
||||
(void)fprintf(stderr,
|
||||
"%s: option requires an argument -- %s\n",
|
||||
__progname(nargv[0]), current_argv);
|
||||
return (BADARG);
|
||||
}
|
||||
} else { /* No matching argument */
|
||||
if ((opterr) && (*options != ':'))
|
||||
(void)fprintf(stderr,
|
||||
"%s: illegal option -- %s\n", __progname(nargv[0]), current_argv);
|
||||
return (BADCH);
|
||||
}
|
||||
if (long_options[match].flag) {
|
||||
*long_options[match].flag = long_options[match].val;
|
||||
retval = 0;
|
||||
} else
|
||||
retval = long_options[match].val;
|
||||
if (index)
|
||||
*index = match;
|
||||
}
|
||||
return(retval);
|
||||
}
|
||||
/*****************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "getopt.h"
|
||||
|
||||
/* Stuff for getopt */
|
||||
static struct option long_options[] = {
|
||||
{ (char *)"simple", 0, NULL, 's' },
|
||||
{ (char *)"t", 0, NULL, 't' },
|
||||
{ (char *)"u", 1, NULL, 'u' },
|
||||
{ (char *)"v", 0, NULL, 'v' },
|
||||
/* Do not reorder the following */
|
||||
{ (char *)"yy", 0, NULL, 'Y' },
|
||||
{ (char *)"y", 0, NULL, 'y' },
|
||||
{ (char *)"zz", 0, NULL, 'z' },
|
||||
{ (char *)"zzz", 0, NULL, 'Z' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
extern char * optarg;
|
||||
extern int optreset;
|
||||
extern int optind;
|
||||
|
||||
int test_getopt_long(args, expected_result)
|
||||
char ** args, * expected_result;
|
||||
{
|
||||
char actual_result[256];
|
||||
int count, pass, i;
|
||||
|
||||
pass = 0;
|
||||
optind = 1;
|
||||
optreset = 1;
|
||||
for (count = 0; args[count]; count++);
|
||||
while ((i = getopt_long(count, args, (char *)"ab:", long_options, NULL)) != EOF) {
|
||||
switch(i) {
|
||||
case 'u':
|
||||
if (strcmp(optarg, "bogus")) {
|
||||
printf("--u option does not have bogus optarg.\n");
|
||||
return(1);
|
||||
}
|
||||
case 'Y':
|
||||
case 's':
|
||||
case 't':
|
||||
case 'v':
|
||||
case 'y':
|
||||
case 'z':
|
||||
actual_result[pass++] = i;
|
||||
break;
|
||||
default:
|
||||
actual_result[pass++] = '?';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
actual_result[pass] = '\0';
|
||||
return(strcmp(actual_result, expected_result));
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
int usage(value)
|
||||
int value;
|
||||
{
|
||||
printf("test_getopt [-d]\n");
|
||||
exit(value);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
* Static arglists for individual tests
|
||||
* This is ugly and maybe I should just use a variable arglist
|
||||
*/
|
||||
const char *argv1[] = { "Test simple", "--s", NULL };
|
||||
const char *argv2[] = { "Test multiple", "--s", "--t", NULL };
|
||||
const char *argv3[] = { "Test optarg with space", "--u", "bogus", NULL };
|
||||
const char *argv4[] = { "Test optarg with equal", "--u=bogus", NULL };
|
||||
const char *argv5[] = { "Test complex", "--s", "--t", "--u", "bogus", "--v", NULL };
|
||||
const char *argv6[] = { "Test exact", "--y", NULL };
|
||||
const char *argv7[] = { "Test abbr", "--z", NULL };
|
||||
const char *argv8[] = { "Test simple termination", "--z", "foo", "--z", NULL };
|
||||
const char *argv9[] = { "Test -- termination", "--z", "--", "--z", NULL };
|
||||
|
||||
int debug = 0;
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char ** argv;
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Of course if getopt() has a bug this won't work */
|
||||
while ((i = getopt(argc, argv, "d")) != EOF) {
|
||||
switch(i) {
|
||||
case 'd':
|
||||
debug++;
|
||||
break;
|
||||
default:
|
||||
usage(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Test getopt_long() */
|
||||
{
|
||||
if (test_getopt_long(argv1, "s")) {
|
||||
printf("Test simple failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test multiple arguments */
|
||||
{
|
||||
if (test_getopt_long(argv2, "st")) {
|
||||
printf("Test multiple failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test optarg with space */
|
||||
{
|
||||
if (test_getopt_long(argv3, "u")) {
|
||||
printf("Test optarg with space failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test optarg with equal */
|
||||
{
|
||||
if (test_getopt_long(argv4, "u")) {
|
||||
printf("Test optarg with equal failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test complex */
|
||||
{
|
||||
if (test_getopt_long(argv5, "stuv")) {
|
||||
printf("Test complex failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test that exact matches override abbr matches */
|
||||
{
|
||||
if (test_getopt_long(argv6, "y")) {
|
||||
printf("Test exact failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test that abbr matches are first match. */
|
||||
{
|
||||
if (test_getopt_long(argv7, "z")) {
|
||||
printf("Test abbr failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test that option termination succeeds */
|
||||
{
|
||||
if (test_getopt_long(argv8, "z")) {
|
||||
printf("Test simple termination failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test that "--" termination succeeds */
|
||||
{
|
||||
if (test_getopt_long(argv9, "z")) {
|
||||
printf("Test -- termination failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
95
winsup/cygwin/libccrt0.cc
Normal file
95
winsup/cygwin/libccrt0.cc
Normal file
@ -0,0 +1,95 @@
|
||||
/* libccrt0.cc: crt0 for libc [newlib calls this one]
|
||||
|
||||
Copyright 1996, 1998, 1999, 2000 Cygnus Solutions.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#undef MALLOC_DEBUG
|
||||
|
||||
#include "winsup.h"
|
||||
#include <reent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef int (*MainFunc) (int argc, char *argc[], char **env);
|
||||
|
||||
extern "C"
|
||||
{
|
||||
char **environ;
|
||||
void cygwin_crt0 (MainFunc);
|
||||
int cygwin_attach_dll (HMODULE, MainFunc);
|
||||
int cygwin_attach_noncygwin_dll (HMODULE, MainFunc);
|
||||
int main (int, char **, char **);
|
||||
struct _reent *_impure_ptr;
|
||||
int _fmode;
|
||||
};
|
||||
|
||||
static per_process this_proc;
|
||||
|
||||
/* Set up pointers to various pieces so the dll can then use them,
|
||||
and then jump to the dll. */
|
||||
|
||||
static void
|
||||
cygwin_crt0_common (MainFunc f)
|
||||
{
|
||||
/* This is used to record what the initial sp was. The value is needed
|
||||
when copying the parent's stack to the child during a fork. */
|
||||
int onstack;
|
||||
|
||||
/* The version numbers are the main source of compatibility checking.
|
||||
As a backup to them, we use the size of the per_process struct. */
|
||||
this_proc.magic_biscuit = sizeof (per_process);
|
||||
|
||||
/* cygwin.dll version number in effect at the time the app was created. */
|
||||
this_proc.dll_major = CYGWIN_VERSION_DLL_MAJOR;
|
||||
this_proc.dll_minor = CYGWIN_VERSION_DLL_MINOR;
|
||||
this_proc.api_major = CYGWIN_VERSION_API_MAJOR;
|
||||
this_proc.api_minor = CYGWIN_VERSION_API_MINOR;
|
||||
|
||||
this_proc.ctors = &__CTOR_LIST__;
|
||||
this_proc.dtors = &__DTOR_LIST__;
|
||||
this_proc.envptr = &environ;
|
||||
this_proc.impure_ptr_ptr = &_impure_ptr;
|
||||
this_proc.main = f;
|
||||
this_proc.fmode_ptr = &_fmode;
|
||||
this_proc.initial_sp = (char *) &onstack;
|
||||
|
||||
/* Remember whatever the user linked his application with - or
|
||||
point to entries in the dll. */
|
||||
this_proc.malloc = &malloc;
|
||||
this_proc.free = &free;
|
||||
this_proc.realloc = &realloc;
|
||||
this_proc.calloc = &calloc;
|
||||
|
||||
/* Setup the module handle so fork can get the path name. */
|
||||
this_proc.hmodule = GetModuleHandle (0);
|
||||
|
||||
/* variables for fork */
|
||||
this_proc.data_start = &_data_start__;
|
||||
this_proc.data_end = &_data_end__;
|
||||
this_proc.bss_start = &_bss_start__;
|
||||
this_proc.bss_end = &_bss_end__;
|
||||
}
|
||||
|
||||
/* for main module */
|
||||
void
|
||||
cygwin_crt0 (MainFunc f)
|
||||
{
|
||||
cygwin_crt0_common (f);
|
||||
|
||||
/* Jump into the dll. */
|
||||
dll_crt0 (&this_proc);
|
||||
}
|
||||
|
||||
/* for a loaded dll */
|
||||
int
|
||||
cygwin_attach_dll (HMODULE h, MainFunc f)
|
||||
{
|
||||
cygwin_crt0_common (f);
|
||||
|
||||
/* jump into the dll. */
|
||||
return dll_dllcrt0 (h, &this_proc);
|
||||
}
|
34
winsup/cygwin/libcmain.cc
Normal file
34
winsup/cygwin/libcmain.cc
Normal file
@ -0,0 +1,34 @@
|
||||
/* libcmain.cc
|
||||
|
||||
Copyright 1996, 1997, 1998 Cygnus Solutions.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* Allow apps which don't have a main work, as long as they define WinMain */
|
||||
extern "C" int main ()
|
||||
{
|
||||
HMODULE x = GetModuleHandleA(0);
|
||||
char *s = GetCommandLineA ();
|
||||
STARTUPINFO si;
|
||||
|
||||
/* GetCommandLineA returns the entire command line including the
|
||||
program name, but WinMain is defined to accept the command
|
||||
line without the program name. */
|
||||
while (*s != ' ' && *s != '\0')
|
||||
++s;
|
||||
while (*s == ' ')
|
||||
++s;
|
||||
|
||||
GetStartupInfo (&si);
|
||||
|
||||
WinMain (x, 0, s,
|
||||
((si.dwFlags & STARTF_USESHOWWINDOW) != 0
|
||||
? si.wShowWindow
|
||||
: SW_SHOWNORMAL));
|
||||
}
|
2250
winsup/cygwin/localtime.c
Normal file
2250
winsup/cygwin/localtime.c
Normal file
File diff suppressed because it is too large
Load Diff
24
winsup/cygwin/regexp/regerror.c
Normal file
24
winsup/cygwin/regexp/regerror.c
Normal file
@ -0,0 +1,24 @@
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char *rcsid = "$Id$";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
#include "regexp.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void
|
||||
regerror(s)
|
||||
const char *s;
|
||||
{
|
||||
#ifdef ERRAVAIL
|
||||
error("regexp: %s", s);
|
||||
#else
|
||||
/*
|
||||
fprintf(stderr, "regexp(3): %s\n", s);
|
||||
exit(1);
|
||||
*/
|
||||
return; /* let std. egrep handle errors */
|
||||
#endif
|
||||
/* NOTREACHED */
|
||||
}
|
321
winsup/cygwin/regexp/regexp.3
Normal file
321
winsup/cygwin/regexp/regexp.3
Normal file
@ -0,0 +1,321 @@
|
||||
.\" Copyright (c) 1991, 1993
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" @(#)regexp.3 8.1 (Berkeley) 6/4/93
|
||||
.\"
|
||||
.Dd June 4, 1993
|
||||
.Dt REGEXP 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm regcomp ,
|
||||
.Nm regexec ,
|
||||
.Nm regsub ,
|
||||
.Nm regerror
|
||||
.Nd regular expression handlers
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <regexp.h>
|
||||
.Ft regexp *
|
||||
.Fn regcomp "const char *exp"
|
||||
.Ft int
|
||||
.Fn regexec "const regexp *prog" "const char *string"
|
||||
.Ft void
|
||||
.Fn regsub "const regexp *prog" "const char *source" "char *dest"
|
||||
.Sh DESCRIPTION
|
||||
.Bf -symbolic
|
||||
This interface is made obsolete by
|
||||
.Xr regex 3 .
|
||||
It is available from the compatibility library, libcompat.
|
||||
.Ef
|
||||
.Pp
|
||||
The
|
||||
.Fn regcomp ,
|
||||
.Fn regexec ,
|
||||
.Fn regsub ,
|
||||
and
|
||||
.Fn regerror
|
||||
functions
|
||||
implement
|
||||
.Xr egrep 1 Ns -style
|
||||
regular expressions and supporting facilities.
|
||||
.Pp
|
||||
The
|
||||
.Fn regcomp
|
||||
function
|
||||
compiles a regular expression into a structure of type
|
||||
.Xr regexp ,
|
||||
and returns a pointer to it.
|
||||
The space has been allocated using
|
||||
.Xr malloc 3
|
||||
and may be released by
|
||||
.Xr free .
|
||||
.Pp
|
||||
The
|
||||
.Fn regexec
|
||||
function
|
||||
matches a
|
||||
.Dv NUL Ns -terminated
|
||||
.Fa string
|
||||
against the compiled regular expression
|
||||
in
|
||||
.Fa prog .
|
||||
It returns 1 for success and 0 for failure, and adjusts the contents of
|
||||
.Fa prog Ns 's
|
||||
.Em startp
|
||||
and
|
||||
.Em endp
|
||||
(see below) accordingly.
|
||||
.Pp
|
||||
The members of a
|
||||
.Xr regexp
|
||||
structure include at least the following (not necessarily in order):
|
||||
.Bd -literal -offset indent
|
||||
char *startp[NSUBEXP];
|
||||
char *endp[NSUBEXP];
|
||||
.Ed
|
||||
.Pp
|
||||
where
|
||||
.Dv NSUBEXP
|
||||
is defined (as 10) in the header file.
|
||||
Once a successful
|
||||
.Fn regexec
|
||||
has been done using the
|
||||
.Fn regexp ,
|
||||
each
|
||||
.Em startp Ns - Em endp
|
||||
pair describes one substring
|
||||
within the
|
||||
.Fa string ,
|
||||
with the
|
||||
.Em startp
|
||||
pointing to the first character of the substring and
|
||||
the
|
||||
.Em endp
|
||||
pointing to the first character following the substring.
|
||||
The 0th substring is the substring of
|
||||
.Fa string
|
||||
that matched the whole
|
||||
regular expression.
|
||||
The others are those substrings that matched parenthesized expressions
|
||||
within the regular expression, with parenthesized expressions numbered
|
||||
in left-to-right order of their opening parentheses.
|
||||
.Pp
|
||||
The
|
||||
.Fn regsub
|
||||
function
|
||||
copies
|
||||
.Fa source
|
||||
to
|
||||
.Fa dest ,
|
||||
making substitutions according to the
|
||||
most recent
|
||||
.Fn regexec
|
||||
performed using
|
||||
.Fa prog .
|
||||
Each instance of `&' in
|
||||
.Fa source
|
||||
is replaced by the substring
|
||||
indicated by
|
||||
.Em startp Ns Bq
|
||||
and
|
||||
.Em endp Ns Bq .
|
||||
Each instance of
|
||||
.Sq \e Ns Em n ,
|
||||
where
|
||||
.Em n
|
||||
is a digit, is replaced by
|
||||
the substring indicated by
|
||||
.Em startp Ns Bq Em n
|
||||
and
|
||||
.Em endp Ns Bq Em n .
|
||||
To get a literal `&' or
|
||||
.Sq \e Ns Em n
|
||||
into
|
||||
.Fa dest ,
|
||||
prefix it with `\e';
|
||||
to get a literal `\e' preceding `&' or
|
||||
.Sq \e Ns Em n ,
|
||||
prefix it with
|
||||
another `\e'.
|
||||
.Pp
|
||||
The
|
||||
.Fn regerror
|
||||
function
|
||||
is called whenever an error is detected in
|
||||
.Fn regcomp ,
|
||||
.Fn regexec ,
|
||||
or
|
||||
.Fn regsub .
|
||||
The default
|
||||
.Fn regerror
|
||||
writes the string
|
||||
.Fa msg ,
|
||||
with a suitable indicator of origin,
|
||||
on the standard
|
||||
error output
|
||||
and invokes
|
||||
.Xr exit 2 .
|
||||
The
|
||||
.Fn regerror
|
||||
function
|
||||
can be replaced by the user if other actions are desirable.
|
||||
.Sh REGULAR EXPRESSION SYNTAX
|
||||
A regular expression is zero or more
|
||||
.Em branches ,
|
||||
separated by `|'.
|
||||
It matches anything that matches one of the branches.
|
||||
.Pp
|
||||
A branch is zero or more
|
||||
.Em pieces ,
|
||||
concatenated.
|
||||
It matches a match for the first, followed by a match for the second, etc.
|
||||
.Pp
|
||||
A piece is an
|
||||
.Em atom
|
||||
possibly followed by `*', `+', or `?'.
|
||||
An atom followed by `*' matches a sequence of 0 or more matches of the atom.
|
||||
An atom followed by `+' matches a sequence of 1 or more matches of the atom.
|
||||
An atom followed by `?' matches a match of the atom, or the null string.
|
||||
.Pp
|
||||
An atom is a regular expression in parentheses (matching a match for the
|
||||
regular expression), a
|
||||
.Em range
|
||||
(see below), `.'
|
||||
(matching any single character), `^' (matching the null string at the
|
||||
beginning of the input string), `$' (matching the null string at the
|
||||
end of the input string), a `\e' followed by a single character (matching
|
||||
that character), or a single character with no other significance
|
||||
(matching that character).
|
||||
.Pp
|
||||
A
|
||||
.Em range
|
||||
is a sequence of characters enclosed in `[]'.
|
||||
It normally matches any single character from the sequence.
|
||||
If the sequence begins with `^',
|
||||
it matches any single character
|
||||
.Em not
|
||||
from the rest of the sequence.
|
||||
If two characters in the sequence are separated by `\-', this is shorthand
|
||||
for the full list of
|
||||
.Tn ASCII
|
||||
characters between them
|
||||
(e.g. `[0-9]' matches any decimal digit).
|
||||
To include a literal `]' in the sequence, make it the first character
|
||||
(following a possible `^').
|
||||
To include a literal `\-', make it the first or last character.
|
||||
.Sh AMBIGUITY
|
||||
If a regular expression could match two different parts of the input string,
|
||||
it will match the one which begins earliest.
|
||||
If both begin in the same place but match different lengths, or match
|
||||
the same length in different ways, life gets messier, as follows.
|
||||
.Pp
|
||||
In general, the possibilities in a list of branches are considered in
|
||||
left-to-right order, the possibilities for `*', `+', and `?' are
|
||||
considered longest-first, nested constructs are considered from the
|
||||
outermost in, and concatenated constructs are considered leftmost-first.
|
||||
The match that will be chosen is the one that uses the earliest
|
||||
possibility in the first choice that has to be made.
|
||||
If there is more than one choice, the next will be made in the same manner
|
||||
(earliest possibility) subject to the decision on the first choice.
|
||||
And so forth.
|
||||
.Pp
|
||||
For example,
|
||||
.Sq Li (ab|a)b*c
|
||||
could match
|
||||
`abc' in one of two ways.
|
||||
The first choice is between `ab' and `a'; since `ab' is earlier, and does
|
||||
lead to a successful overall match, it is chosen.
|
||||
Since the `b' is already spoken for,
|
||||
the `b*' must match its last possibility\(emthe empty string\(emsince
|
||||
it must respect the earlier choice.
|
||||
.Pp
|
||||
In the particular case where no `|'s are present and there is only one
|
||||
`*', `+', or `?', the net effect is that the longest possible
|
||||
match will be chosen.
|
||||
So
|
||||
.Sq Li ab* ,
|
||||
presented with `xabbbby', will match `abbbb'.
|
||||
Note that if
|
||||
.Sq Li ab* ,
|
||||
is tried against `xabyabbbz', it
|
||||
will match `ab' just after `x', due to the begins-earliest rule.
|
||||
(In effect, the decision on where to start the match is the first choice
|
||||
to be made, hence subsequent choices must respect it even if this leads them
|
||||
to less-preferred alternatives.)
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn regcomp
|
||||
function
|
||||
returns
|
||||
.Dv NULL
|
||||
for a failure
|
||||
.Pf ( Fn regerror
|
||||
permitting),
|
||||
where failures are syntax errors, exceeding implementation limits,
|
||||
or applying `+' or `*' to a possibly-null operand.
|
||||
.Sh SEE ALSO
|
||||
.Xr ed 1 ,
|
||||
.Xr ex 1 ,
|
||||
.Xr expr 1 ,
|
||||
.Xr egrep 1 ,
|
||||
.Xr fgrep 1 ,
|
||||
.Xr grep 1 ,
|
||||
.Xr regex 3
|
||||
.Sh HISTORY
|
||||
Both code and manual page for
|
||||
.Fn regcomp ,
|
||||
.Fn regexec ,
|
||||
.Fn regsub ,
|
||||
and
|
||||
.Fn regerror
|
||||
were written at the University of Toronto
|
||||
and appeared in
|
||||
.Bx 4.3 tahoe .
|
||||
They are intended to be compatible with the Bell V8
|
||||
.Xr regexp 3 ,
|
||||
but are not derived from Bell code.
|
||||
.Sh BUGS
|
||||
Empty branches and empty regular expressions are not portable to V8.
|
||||
.Pp
|
||||
The restriction against
|
||||
applying `*' or `+' to a possibly-null operand is an artifact of the
|
||||
simplistic implementation.
|
||||
.Pp
|
||||
Does not support
|
||||
.Xr egrep Ns 's
|
||||
newline-separated branches;
|
||||
neither does the V8
|
||||
.Xr regexp 3 ,
|
||||
though.
|
||||
.Pp
|
||||
Due to emphasis on
|
||||
compactness and simplicity,
|
||||
it's not strikingly fast.
|
||||
It does give special attention to handling simple cases quickly.
|
1326
winsup/cygwin/regexp/regexp.c
Normal file
1326
winsup/cygwin/regexp/regexp.c
Normal file
File diff suppressed because it is too large
Load Diff
87
winsup/cygwin/regexp/regsub.c
Normal file
87
winsup/cygwin/regexp/regsub.c
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* regsub
|
||||
*
|
||||
* Copyright (c) 1986 by University of Toronto.
|
||||
* Written by Henry Spencer. Not derived from licensed software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any
|
||||
* purpose on any computer system, and to redistribute it freely,
|
||||
* subject to the following restrictions:
|
||||
*
|
||||
* 1. The author is not responsible for the consequences of use of
|
||||
* this software, no matter how awful, even if they arise
|
||||
* from defects in it.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either
|
||||
* by explicit claim or by omission.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char *rcsid = "$Id$";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
#include "regexp.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "regmagic.h"
|
||||
|
||||
#ifndef CHARBITS
|
||||
#define UCHARAT(p) ((int)*(unsigned char *)(p))
|
||||
#else
|
||||
#define UCHARAT(p) ((int)*(p)&CHARBITS)
|
||||
#endif
|
||||
|
||||
/*
|
||||
- regsub - perform substitutions after a regexp match
|
||||
*/
|
||||
void
|
||||
regsub(prog, source, dest)
|
||||
const regexp *prog;
|
||||
const char *source;
|
||||
char *dest;
|
||||
{
|
||||
register char *src;
|
||||
register char *dst;
|
||||
register char c;
|
||||
register int no;
|
||||
register int len;
|
||||
|
||||
if (prog == NULL || source == NULL || dest == NULL) {
|
||||
regerror("NULL parm to regsub");
|
||||
return;
|
||||
}
|
||||
if (UCHARAT(prog->program) != MAGIC) {
|
||||
regerror("damaged regexp fed to regsub");
|
||||
return;
|
||||
}
|
||||
|
||||
src = (char *)source;
|
||||
dst = dest;
|
||||
while ((c = *src++) != '\0') {
|
||||
if (c == '&')
|
||||
no = 0;
|
||||
else if (c == '\\' && '0' <= *src && *src <= '9')
|
||||
no = *src++ - '0';
|
||||
else
|
||||
no = -1;
|
||||
if (no < 0) { /* Ordinary character. */
|
||||
if (c == '\\' && (*src == '\\' || *src == '&'))
|
||||
c = *src++;
|
||||
*dst++ = c;
|
||||
} else if (prog->startp[no] != NULL && prog->endp[no] != NULL) {
|
||||
len = prog->endp[no] - prog->startp[no];
|
||||
(void) strncpy(dst, prog->startp[no], len);
|
||||
dst += len;
|
||||
if (len != 0 && *(dst-1) == '\0') { /* strncpy hit NUL. */
|
||||
regerror("damaged match string");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
*dst++ = '\0';
|
||||
}
|
552
winsup/cygwin/shared.h
Normal file
552
winsup/cygwin/shared.h
Normal file
@ -0,0 +1,552 @@
|
||||
/* shared.h: shared info for cygwin
|
||||
|
||||
Copyright 1998, 1999, 2000 Cygnus Solutions.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
/******** Functions declarations for use in methods below ********/
|
||||
|
||||
/* Printf type functions */
|
||||
extern "C" void __api_fatal (const char *, ...) __attribute__ ((noreturn));
|
||||
extern "C" int __small_sprintf (char *dst, const char *fmt, ...);
|
||||
extern "C" int __small_vsprintf (char *dst, const char *fmt, va_list ap);
|
||||
extern "C" int __small_sprintf (char *dst, const char *fmt, ...);
|
||||
|
||||
/******** Deletion Queue Class ********/
|
||||
|
||||
/* First pass at a file deletion queue structure.
|
||||
|
||||
We can't keep this list in the per-process info, since
|
||||
one process may open a file, and outlive a process which
|
||||
wanted to unlink the file - and the data would go away.
|
||||
|
||||
Perhaps the FILE_FLAG_DELETE_ON_CLOSE would be ok,
|
||||
but brief experimentation didn't get too far.
|
||||
*/
|
||||
|
||||
#define MAX_DELQUEUES_PENDING 100
|
||||
|
||||
class delqueue_list
|
||||
{
|
||||
char name[MAX_DELQUEUES_PENDING][MAX_PATH];
|
||||
char inuse[MAX_DELQUEUES_PENDING];
|
||||
int empty;
|
||||
|
||||
public:
|
||||
void init ();
|
||||
void queue_file (const char *dosname);
|
||||
void process_queue ();
|
||||
};
|
||||
|
||||
/******** Process Table ********/
|
||||
|
||||
/* Signal constants (have to define them here, unfortunately) */
|
||||
|
||||
enum
|
||||
{
|
||||
__SIGFLUSH = -2,
|
||||
__SIGSTRACE = -1,
|
||||
__SIGCHILDSTOPPED = 0,
|
||||
__SIGOFFSET = 3
|
||||
};
|
||||
|
||||
class pinfo
|
||||
{
|
||||
public:
|
||||
|
||||
/* If hProcess is set, it's because it came from a
|
||||
CreateProcess call. This means it's process relative
|
||||
to the thing which created the process. That's ok because
|
||||
we only use this handle from the parent. */
|
||||
HANDLE hProcess;
|
||||
|
||||
HANDLE parent_alive;
|
||||
|
||||
/* dwProcessId contains the processid used for sending signals. It
|
||||
* will be reset in a child process when it is capable of receiving
|
||||
* signals.
|
||||
*/
|
||||
DWORD dwProcessId;
|
||||
|
||||
/* User information.
|
||||
The information is derived from the GetUserName system call,
|
||||
with the name looked up in /etc/passwd and assigned a default value
|
||||
if not found. This data resides in the shared data area (allowing
|
||||
tasks to store whatever they want here) so it's for informational
|
||||
purposes only. */
|
||||
uid_t uid; /* User ID */
|
||||
gid_t gid; /* Group ID */
|
||||
pid_t pgid; /* Process group ID */
|
||||
pid_t sid; /* Session ID */
|
||||
int ctty; /* Control tty */
|
||||
mode_t umask;
|
||||
char username[MAX_USER_NAME]; /* user's name */
|
||||
|
||||
/* Extendend user information.
|
||||
The information is derived from the internal_getlogin call
|
||||
when on a NT system. */
|
||||
PSID psid; /* user's SID */
|
||||
char sidbuf[40]; /* buffer for user's SID */
|
||||
char logsrv[256]; /* Logon server, may be fully qualified DNS name */
|
||||
char domain[MAX_COMPUTERNAME_LENGTH+1]; /* Logon domain of the user */
|
||||
|
||||
/* Non-zero if process was stopped by a signal. */
|
||||
char stopsig;
|
||||
|
||||
struct sigaction& getsig (int);
|
||||
void copysigs (pinfo *);
|
||||
sigset_t& getsigmask ();
|
||||
void setsigmask (sigset_t);
|
||||
LONG* getsigtodo (int);
|
||||
HANDLE getthread2signal ();
|
||||
void setthread2signal (void *);
|
||||
|
||||
/* Resources used by process. */
|
||||
long start_time;
|
||||
struct rusage rusage_self;
|
||||
struct rusage rusage_children;
|
||||
|
||||
private:
|
||||
struct sigaction sigs[NSIG];
|
||||
sigset_t sig_mask; /* one set for everything to ignore. */
|
||||
LONG _sigtodo[NSIG + __SIGOFFSET];
|
||||
#ifdef _MT_SAFE
|
||||
ThreadItem* thread2signal; // NULL means means thread any other means a pthread
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
/* Pointer to mmap'ed areas for this process. Set up by fork. */
|
||||
void *mmap_ptr;
|
||||
|
||||
/* Used to spawn a child for fork(), among other things. */
|
||||
char progname[MAX_PATH];
|
||||
|
||||
#define PINFO_ZERO ((((pinfo *) NULL)->progname + 1) - ((char *) NULL))
|
||||
|
||||
/* Anything below this point is not zeroed automatically by allocate_pid */
|
||||
|
||||
/* The pid stays the same, while the hProcess moves due to execs. */
|
||||
pid_t pid;
|
||||
/* Parent process id. */
|
||||
pid_t ppid;
|
||||
|
||||
/* Various flags indicating the state of the process. See PID_
|
||||
constants below. */
|
||||
DWORD process_state;
|
||||
|
||||
void record_death (int lock = 1);
|
||||
};
|
||||
|
||||
#define ISSTATE(p, f) (!!((p)->process_state & f))
|
||||
#define NOTSTATE(p, f) (!((p)->process_state & f))
|
||||
|
||||
/* Flags associated with process_state */
|
||||
enum
|
||||
{
|
||||
PID_NOT_IN_USE = 0x0000, // Free entry.
|
||||
PID_IN_USE = 0x0001, // Entry in use.
|
||||
PID_ZOMBIE = 0x0002, // Child exited: no parent wait.
|
||||
PID_STOPPED = 0x0004, // Waiting for SIGCONT.
|
||||
PID_TTYIN = 0x0008, // Waiting for terminal input.
|
||||
PID_TTYOU = 0x0010, // Waiting for terminal output.
|
||||
PID_ORPHANED = 0x0020, // Member of an orphaned process group.
|
||||
PID_ACTIVE = 0x0040, // Pid accepts signals.
|
||||
PID_CYGPARENT = 0x0080, // Set if parent was a cygwin app.
|
||||
PID_SPLIT_HEAP = 0x0100, // Set if the heap has been split,
|
||||
// which means we can't fork again.
|
||||
PID_CLEAR = 0x0200, // Flag that pid should be cleared from parent's
|
||||
// wait list
|
||||
PID_SOCKETS_USED = 0x0400, // Set if process uses Winsock.
|
||||
PID_INITIALIZING = 0x0800, // Set until ready to receive signals.
|
||||
PID_USETTY = 0x1000, // Setting this enables or disables cygwin's
|
||||
// tty support. This is inherited by
|
||||
// all execed or forked processes.
|
||||
PID_REPARENT = 0x2000 // child has execed
|
||||
};
|
||||
|
||||
#define PSIZE 128
|
||||
|
||||
class pinfo_list
|
||||
{
|
||||
public:
|
||||
int next_pid;
|
||||
pinfo vec[PSIZE];
|
||||
char lock_info[MAX_PATH + 1];
|
||||
pinfo * operator[] (pid_t x);
|
||||
int size (void) { return PSIZE; }
|
||||
pinfo *allocate_pid (void);
|
||||
void init (void);
|
||||
};
|
||||
|
||||
void __stdcall pinfo_init (PBYTE);
|
||||
pinfo *__stdcall procinfo (int n);
|
||||
|
||||
enum
|
||||
{
|
||||
PROC_MAGIC = 0xaf04f000,
|
||||
PROC_FORK = PROC_MAGIC + 1,
|
||||
PROC_EXEC = PROC_MAGIC + 2,
|
||||
PROC_SPAWN = PROC_MAGIC + 3,
|
||||
PROC_FORK1 = PROC_MAGIC + 4 // Newer versions provide stack
|
||||
// location information
|
||||
};
|
||||
|
||||
#define PROC_MAGIC_MASK 0xff00f000
|
||||
#define PROC_MAGIC_GENERIC 0xaf00f000
|
||||
#define PROC_MAGIC_VER_MASK 0x0ff0000
|
||||
|
||||
#define EXEC_MAGIC_SIZE sizeof(child_info)
|
||||
class child_info
|
||||
{
|
||||
public:
|
||||
DWORD zero[1]; // must be zeroed
|
||||
DWORD cb; // size of this record
|
||||
DWORD type; // type of record
|
||||
int cygpid; // cygwin pid of child process
|
||||
HANDLE subproc_ready; // used for synchronization with parent
|
||||
HANDLE shared_h;
|
||||
HANDLE console_h;
|
||||
HANDLE parent_alive; // handle of thread used to track children
|
||||
};
|
||||
|
||||
class child_info_fork: public child_info
|
||||
{
|
||||
public:
|
||||
HANDLE forker_finished;// for synchronization with child
|
||||
DWORD stacksize; // size of parent stack
|
||||
void *heaptop;
|
||||
void *heapbase;
|
||||
void *heapptr;
|
||||
jmp_buf jmp; // where child will jump to
|
||||
void *stacktop; // location of top of parent stack
|
||||
void *stackbottom; // location of bottom of parent stack
|
||||
};
|
||||
|
||||
void __stdcall init_child_info (DWORD, child_info *, int, HANDLE);
|
||||
|
||||
extern child_info_fork *child_proc_info;
|
||||
|
||||
/* Process info for this process */
|
||||
extern pinfo *myself;
|
||||
|
||||
/* non-NULL if this process is a child of a cygwin process */
|
||||
extern HANDLE parent_alive;
|
||||
|
||||
/******** Registry Access ********/
|
||||
|
||||
class reg_key
|
||||
{
|
||||
private:
|
||||
|
||||
HKEY key;
|
||||
|
||||
public:
|
||||
|
||||
reg_key (HKEY toplev, REGSAM access, ...);
|
||||
reg_key (REGSAM access, ...);
|
||||
reg_key (REGSAM access = KEY_ALL_ACCESS);
|
||||
|
||||
void *operator new (size_t, void *p) {return p;}
|
||||
void build_reg (HKEY key, REGSAM access, va_list av);
|
||||
|
||||
int error () {return key == (HKEY) INVALID_HANDLE_VALUE;}
|
||||
|
||||
int kill (const char *child);
|
||||
|
||||
HKEY get_key ();
|
||||
int get_int (const char *,int def);
|
||||
int get_string (const char *, char *buf, size_t len, const char *def);
|
||||
int set_string (const char *,const char *);
|
||||
int set_int (const char *, int val);
|
||||
int setone_string (const char *src, const char *name);
|
||||
|
||||
~reg_key ();
|
||||
};
|
||||
|
||||
/******** Mount Table ********/
|
||||
|
||||
/* Mount table entry */
|
||||
|
||||
class mount_item
|
||||
{
|
||||
public:
|
||||
/* FIXME: Nasty static allocation. Need to have a heap in the shared
|
||||
area [with the user being able to configure at runtime the max size]. */
|
||||
|
||||
/* Win32-style mounted partition source ("C:\foo\bar").
|
||||
native_path[0] == 0 for unused entries. */
|
||||
char native_path[MAX_PATH];
|
||||
int native_pathlen;
|
||||
|
||||
/* POSIX-style mount point ("/foo/bar") */
|
||||
char posix_path[MAX_PATH];
|
||||
int posix_pathlen;
|
||||
|
||||
unsigned flags;
|
||||
|
||||
void init (const char *dev, const char *path, unsigned flags);
|
||||
|
||||
struct mntent *getmntent ();
|
||||
};
|
||||
|
||||
/* Warning: Decreasing this value will cause cygwin.dll to ignore existing
|
||||
higher numbered registry entries. Don't change this number willy-nilly.
|
||||
What we need is to have a more dynamic allocation scheme, but the current
|
||||
scheme should be satisfactory for a long while yet. */
|
||||
#define MAX_MOUNTS 30
|
||||
|
||||
class mount_info
|
||||
{
|
||||
int posix_sorted[MAX_MOUNTS];
|
||||
int native_sorted[MAX_MOUNTS];
|
||||
public:
|
||||
int nmounts;
|
||||
mount_item mount[MAX_MOUNTS];
|
||||
|
||||
/* Strings used by getmntent(). */
|
||||
char mnt_type[20];
|
||||
char mnt_opts[20];
|
||||
char mnt_fsname[MAX_PATH];
|
||||
char mnt_dir[MAX_PATH];
|
||||
|
||||
/* cygdrive_prefix is used as the root of the path automatically
|
||||
prepended to a path when the path has no associated mount.
|
||||
cygdrive_flags are the default flags for the cygdrives. */
|
||||
char cygdrive[MAX_PATH];
|
||||
size_t cygdrive_len;
|
||||
unsigned cygdrive_flags;
|
||||
|
||||
/* Increment when setting up a reg_key if mounts area had to be
|
||||
created so we know when we need to import old mount tables. */
|
||||
int had_to_create_mount_areas;
|
||||
|
||||
void init ();
|
||||
int add_item (const char *dev, const char *path, unsigned flags);
|
||||
int del_item (const char *path, unsigned flags);
|
||||
|
||||
void from_registry ();
|
||||
void from_v1_registry ();
|
||||
int add_reg_mount (const char * native_path, const char * posix_path,
|
||||
unsigned mountflags);
|
||||
int del_reg_mount (const char * posix_path, unsigned mountflags);
|
||||
|
||||
unsigned set_flags_from_win32_path (const char *path);
|
||||
int conv_to_win32_path (const char *src_path, char *win32_path,
|
||||
char *full_win32_path, DWORD &devn, int &unit,
|
||||
unsigned *flags = NULL);
|
||||
int conv_to_posix_path (const char *src_path, char *posix_path,
|
||||
int keep_rel_p);
|
||||
struct mntent *getmntent (int x);
|
||||
|
||||
int write_cygdrive_info_to_registry (const char *cygdrive_prefix, unsigned flags);
|
||||
|
||||
void import_v1_mounts ();
|
||||
|
||||
private:
|
||||
|
||||
void sort ();
|
||||
void read_mounts (reg_key& r);
|
||||
void read_v1_mounts (reg_key r, unsigned which);
|
||||
void mount_slash ();
|
||||
void to_registry ();
|
||||
|
||||
int cygdrive_win32_path (const char *src, char *dst, int trailing_slash_p);
|
||||
void cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p);
|
||||
void slash_drive_to_win32_path (const char *path, char *buf, int trailing_slash_p);
|
||||
void read_cygdrive_info_from_registry ();
|
||||
};
|
||||
|
||||
/******** TTY Support ********/
|
||||
|
||||
/* tty tables */
|
||||
|
||||
#define INP_BUFFER_SIZE 256
|
||||
#define OUT_BUFFER_SIZE 256
|
||||
#define NTTYS 128
|
||||
#define TTY_CONSOLE 0x40000000
|
||||
#define tty_attached(p) ((p)->ctty >= 0 && (p)->ctty != TTY_CONSOLE)
|
||||
|
||||
/* Input/Output/ioctl events */
|
||||
|
||||
#define OUTPUT_DONE_EVENT "cygtty%d.output.done"
|
||||
#define IOCTL_REQUEST_EVENT "cygtty%d.ioctl.request"
|
||||
#define IOCTL_DONE_EVENT "cygtty%d.ioctl.done"
|
||||
#define RESTART_OUTPUT_EVENT "cygtty%d.output.restart"
|
||||
#define OUTPUT_MUTEX "cygtty%d.output.mutex"
|
||||
#define TTY_SLAVE_ALIVE "cygtty%x.slave_alive"
|
||||
#define TTY_MASTER_ALIVE "cygtty%x.master_alive"
|
||||
|
||||
#include <sys/termios.h>
|
||||
|
||||
enum
|
||||
{
|
||||
TTY_INITIALIZED = 1, /* Set if tty is initialized */
|
||||
TTY_RSTCONS = 2 /* Set if console needs to be set to "non-cooked" */
|
||||
};
|
||||
|
||||
#define TTYISSETF(x) __ISSETF (tc, x, TTY)
|
||||
#define TTYSETF(x) __SETF (tc, x, TTY)
|
||||
#define TTYCLEARF(x) __CLEARF (tc, x, TTY)
|
||||
#define TTYCONDSETF(n, x) __CONDSETF(n, tc, x, TTY)
|
||||
|
||||
#ifndef MIN_CTRL_C_SLOP
|
||||
#define MIN_CTRL_C_SLOP 50
|
||||
#endif
|
||||
|
||||
class tty_min
|
||||
{
|
||||
pid_t sid; /* Session ID of tty */
|
||||
public:
|
||||
DWORD status;
|
||||
pid_t pgid;
|
||||
int OutputStopped;
|
||||
int ntty;
|
||||
DWORD last_ctrl_c; // tick count of last ctrl-c
|
||||
|
||||
tty_min (int t = -1, pid_t s = -1) : sid (s), ntty (t) {}
|
||||
void setntty (int n) {ntty = n;}
|
||||
pid_t getpgid () {return pgid;}
|
||||
void setpgid (int pid) {pgid = pid;}
|
||||
int getsid () {return sid;}
|
||||
void setsid (pid_t tsid) {sid = tsid;}
|
||||
struct termios ti;
|
||||
struct winsize winsize;
|
||||
|
||||
/* ioctl requests buffer */
|
||||
int cmd;
|
||||
union
|
||||
{
|
||||
struct termios termios;
|
||||
struct winsize winsize;
|
||||
int value;
|
||||
pid_t pid;
|
||||
} arg;
|
||||
/* XXX_retval variables holds master's completion codes. Error are stored as
|
||||
* -ERRNO
|
||||
*/
|
||||
int ioctl_retval;
|
||||
|
||||
int write_retval;
|
||||
};
|
||||
|
||||
class fhandler_pty_master;
|
||||
|
||||
class tty: public tty_min
|
||||
{
|
||||
HANDLE get_event (const char *fmt, BOOL inherit);
|
||||
public:
|
||||
HWND hwnd; /* Console window handle tty belongs to */
|
||||
|
||||
DWORD master_pid; /* Win32 PID of tty master process */
|
||||
|
||||
HANDLE from_master, to_slave;
|
||||
HANDLE from_slave, to_master;
|
||||
|
||||
int read_retval;
|
||||
BOOL was_opened; /* True if opened at least once. */
|
||||
|
||||
void init ();
|
||||
HANDLE create_inuse (const char *);
|
||||
BOOL common_init (fhandler_pty_master *);
|
||||
BOOL alive (const char *fmt);
|
||||
BOOL slave_alive ();
|
||||
BOOL master_alive ();
|
||||
HWND gethwnd () {return hwnd;}
|
||||
void sethwnd (HWND wnd) {hwnd = wnd;}
|
||||
int make_pipes (fhandler_pty_master *ptym);
|
||||
HANDLE open_output_mutex (BOOL inherit = FALSE)
|
||||
{
|
||||
char buf[80];
|
||||
__small_sprintf (buf, OUTPUT_MUTEX, ntty);
|
||||
return OpenMutex (MUTEX_ALL_ACCESS, inherit, buf);
|
||||
}
|
||||
BOOL exists ()
|
||||
{
|
||||
HANDLE h = open_output_mutex ();
|
||||
if (h)
|
||||
{
|
||||
CloseHandle (h);
|
||||
return 1;
|
||||
}
|
||||
return slave_alive ();
|
||||
}
|
||||
};
|
||||
|
||||
class tty_list
|
||||
{
|
||||
tty ttys[NTTYS];
|
||||
|
||||
public:
|
||||
tty * operator [](int n) {return ttys + n;}
|
||||
int allocate_tty (int n); /* n non zero if allocate a tty, pty otherwise */
|
||||
int connect_tty (int);
|
||||
void terminate ();
|
||||
void init ();
|
||||
tty_min *get_tty (int n);
|
||||
};
|
||||
|
||||
void __stdcall tty_init ();
|
||||
void __stdcall tty_terminate ();
|
||||
int __stdcall attach_tty (int);
|
||||
void __stdcall create_tty_master (int);
|
||||
extern "C" int ttyslot (void);
|
||||
|
||||
/******** Shared Info ********/
|
||||
/* Data accessible to all tasks */
|
||||
|
||||
class shared_info
|
||||
{
|
||||
DWORD inited;
|
||||
|
||||
public:
|
||||
pinfo_list p;
|
||||
|
||||
/* FIXME: Doesn't work if more than one user on system. */
|
||||
mount_info mount;
|
||||
|
||||
int heap_chunk_in_mb;
|
||||
unsigned heap_chunk_size (void);
|
||||
|
||||
tty_list tty;
|
||||
delqueue_list delqueue;
|
||||
void initialize (void);
|
||||
};
|
||||
|
||||
/* Various types of security attributes for use in Create* functions. */
|
||||
extern SECURITY_ATTRIBUTES sec_none, sec_none_nih, sec_all, sec_all_nih;
|
||||
extern SECURITY_ATTRIBUTES *__stdcall sec_user (PVOID sa_buf, PSID sid2 = NULL, BOOL inherit = TRUE);
|
||||
extern SECURITY_ATTRIBUTES *__stdcall sec_user_nih (PVOID sa_buf, PSID sid2 = NULL);
|
||||
|
||||
extern shared_info *cygwin_shared;
|
||||
extern HANDLE cygwin_shared_h;
|
||||
extern HANDLE console_shared_h;
|
||||
extern int __stdcall set_console_state_for_spawn ();
|
||||
|
||||
void __stdcall shared_init (void);
|
||||
void __stdcall shared_terminate (void);
|
||||
|
||||
/* This is for programs that want to access the shared data. */
|
||||
extern "C" class shared_info *cygwin_getshared (void);
|
||||
|
||||
char *__stdcall shared_name (const char *, int);
|
||||
void *__stdcall open_shared (const char *name, HANDLE &shared_h, DWORD size, void *addr);
|
||||
|
||||
struct cygwin_version_info
|
||||
{
|
||||
unsigned short api_major;
|
||||
unsigned short api_minor;
|
||||
unsigned short dll_major;
|
||||
unsigned short dll_minor;
|
||||
unsigned short shared_data;
|
||||
unsigned short mount_registry;
|
||||
const char *dll_build_date;
|
||||
const char shared_id[sizeof (CYGWIN_VERSION_DLL_IDENTIFIER) + 64];
|
||||
};
|
||||
|
||||
extern cygwin_version_info cygwin_version;
|
||||
extern const char *cygwin_version_strings;
|
165
winsup/cygwin/test.c
Normal file
165
winsup/cygwin/test.c
Normal file
@ -0,0 +1,165 @@
|
||||
/* test.c: misc Cygwin testing code
|
||||
|
||||
Copyright 1996, 1998 Cygnus Solutions.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
char a[] ="This is static data";
|
||||
|
||||
void
|
||||
test1()
|
||||
{
|
||||
int depth = 0;
|
||||
while (depth < 5)
|
||||
{
|
||||
int r;
|
||||
printf ("about to fork %d\n", depth);
|
||||
|
||||
r = fork ();
|
||||
|
||||
if (r == 0)
|
||||
{
|
||||
int res;
|
||||
depth++;
|
||||
printf ("************Depth is %d\n", depth);
|
||||
sleep (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("This is the parent, quitting %d\n", depth);
|
||||
sleep (1);
|
||||
exit (1);
|
||||
}
|
||||
printf ("done loop, depth %d\n", depth);
|
||||
}
|
||||
}
|
||||
|
||||
#define N 10
|
||||
int v[N];
|
||||
startup ()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < N; i++)
|
||||
{
|
||||
int r;
|
||||
fflush (stdout);
|
||||
r = fork ();
|
||||
if (r)
|
||||
{
|
||||
v[i] = r;
|
||||
printf ("started %d, were'id %d\n", v[i], GetCurrentProcessId ());
|
||||
fflush (stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* running the child, sleep a bit and exit. */
|
||||
printf ("the fork said 0, were %d\n", GetCurrentProcessId ());
|
||||
fflush (stdout);
|
||||
sleep (2);
|
||||
printf ("Running, and exiting %d\n", i);
|
||||
fflush (stdout);
|
||||
_exit (i + 0x30);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test2()
|
||||
{
|
||||
int i;
|
||||
startup ();
|
||||
sleep (1);
|
||||
/* Wait for them one by one */
|
||||
for (i = 0; i < N; i++)
|
||||
{
|
||||
int res;
|
||||
|
||||
waitpid (v[i], &res, 0);
|
||||
printf ("Process %d gave res %x\n", v[i], res);
|
||||
if (res != (0x30 + i) << 8)
|
||||
printf ("***** BAD *** Process %d gave res %x\n", v[i], res);
|
||||
}
|
||||
}
|
||||
|
||||
test3()
|
||||
{
|
||||
int i;
|
||||
startup ();
|
||||
/* Wait for them all at the same time */
|
||||
for (i = 0; i < N; i++)
|
||||
{
|
||||
int res;
|
||||
wait (&res);
|
||||
printf ("Got res %x\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
test5()
|
||||
{
|
||||
char *c = strdup ("HI STEVE");
|
||||
printf ("c is %s\n", c);
|
||||
free (c);
|
||||
}
|
||||
|
||||
int count;
|
||||
|
||||
main (int ac, char **av)
|
||||
{
|
||||
int r;
|
||||
int done;
|
||||
int test;
|
||||
fprintf (stderr,"TO STDERR\n");
|
||||
if (ac < 2) {
|
||||
printf ("usage: test <n>\n");
|
||||
exit (2);
|
||||
}
|
||||
test = atoi (av[1]);
|
||||
|
||||
printf ("%d %d Hi steve, about to start fork test %d %d.\n",getpid (), count++, test,
|
||||
GetCurrentProcessId ());
|
||||
fflush (stdout);
|
||||
switch (test)
|
||||
{
|
||||
case 1:
|
||||
test1();
|
||||
break;
|
||||
case 2:
|
||||
test2();
|
||||
break;
|
||||
case 3:
|
||||
test3();
|
||||
break;
|
||||
case 4:
|
||||
SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), FOREGROUND_RED);
|
||||
break;
|
||||
case 5:
|
||||
test5();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
free ()
|
||||
{
|
||||
printf ("MY FREE!\n");
|
||||
}
|
||||
|
||||
char b[100000];
|
||||
int i;
|
||||
|
||||
malloc (x)
|
||||
{
|
||||
char *r = b + i;
|
||||
i += x;
|
||||
return r;
|
||||
}
|
||||
|
||||
realloc ()
|
||||
{
|
||||
}
|
42
winsup/cygwin/testsuite/README
Normal file
42
winsup/cygwin/testsuite/README
Normal file
@ -0,0 +1,42 @@
|
||||
1999-12-23 DJ Delorie <dj@cygnus.com>
|
||||
|
||||
Here are some notes about adding and using this testsuite.
|
||||
|
||||
First, all the programs are linked with new-libcygwin.a, which is just
|
||||
like libcygwin.a, except that it wants new-cygwin1.dll, not
|
||||
cygwin1.dll. The testsuite adds the winsup build directory to the
|
||||
PATH so that new-cygwin1.dll can be found by windows during testing.
|
||||
|
||||
Because we'll probably run into complaints about using two DLLs, we
|
||||
run cygrun.exe for each test. All this does is run the test with
|
||||
CreateProcess() so that we don't attempt to do the special code for
|
||||
when a cygwin program calls another cygwin program, as this might be a
|
||||
"multiple cygwins" problem.
|
||||
|
||||
Any test that needs to test command line args or redirection needs to
|
||||
run such a child program itself, as the testsuite will not do any
|
||||
arguments or redirection for it. Same for fork, signals, etc.
|
||||
|
||||
The testsuite/winsup.api subdirectory is for testing the API to
|
||||
cygwin1.dll ONLY. Create other subdirs under testsuite/ for other
|
||||
classes of testing.
|
||||
|
||||
Tests in winsup.api/*.c or winsup.api/*/*.c (only one subdirectory
|
||||
level is allowed) either compile, run, and exit(0) or they fail.
|
||||
Either abort or exit with a non-zero code to indicate failure. Don't
|
||||
print anything to the screen if you can avoid it (except for failure
|
||||
reasons, of course). One .c file per test, no compile options are
|
||||
allowed (we're testing the api, not the compiler).
|
||||
|
||||
Tests whose filename begin with "xf-" will be *expected* to fail, and
|
||||
will "fail" if they compile, run, and return zero. Note that the
|
||||
*only* purpose for adding this feature is to test the testing
|
||||
framework itself. All real tests should NOT be named xf-*, and should
|
||||
pass for real (compile, run, return 0) if the dll is working
|
||||
correctly. Do not use xf-* to "silence" a failure that you know isn't
|
||||
going to get fixed for a while; let it just keep failing. There are
|
||||
five "sample" tests that demonstrate how the framework works and what
|
||||
happens to each condition.
|
||||
|
||||
"make check" will only work if you run it *on* an NT machine.
|
||||
Cross-checking is not supported.
|
6
winsup/cygwin/testsuite/config/default.exp
Normal file
6
winsup/cygwin/testsuite/config/default.exp
Normal file
@ -0,0 +1,6 @@
|
||||
proc winsup_version {} {
|
||||
clone_output "\n[exec grep ^%%% ../new-cygwin1.dll]\n"
|
||||
}
|
||||
|
||||
proc winsup_exit {} {
|
||||
}
|
113
winsup/cygwin/testsuite/winsup.api/devzero.c
Normal file
113
winsup/cygwin/testsuite/winsup.api/devzero.c
Normal file
@ -0,0 +1,113 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
main()
|
||||
{
|
||||
int fd, r, w, l;
|
||||
char buf[1024];
|
||||
char *v;
|
||||
|
||||
fd = open("/dev/zero", O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
fprintf(stderr, "Unable to open /dev/zero for reading\n");
|
||||
perror("The error was");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
l = read(fd, buf, 1024);
|
||||
if (l != 1024)
|
||||
{
|
||||
fprintf(stderr, "Asked to read 1024 bytes, got %d\n", l);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (r=0; r<1024; r++)
|
||||
if (buf[r] != 0)
|
||||
{
|
||||
fprintf(stderr, "/dev/zero returned a byte of %02x at offset %d\n",
|
||||
buf[r], r);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
l = lseek(fd, 4096, 0);
|
||||
if (l != 0)
|
||||
{
|
||||
fprintf(stderr, "l == %d\n", l);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
l = close(fd);
|
||||
if (l != 0)
|
||||
{
|
||||
fprintf(stderr, "close: returned %d\n", l);
|
||||
perror("The error was");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fd = open("/dev/zero", O_WRONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
fprintf(stderr, "Unable to open /dev/zero for writing\n");
|
||||
perror("The error was");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
l = write(fd, buf, 1024);
|
||||
if (l != 1024)
|
||||
{
|
||||
fprintf(stderr, "Asked to write 1024 bytes, got %d\n", l);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
l = close(fd);
|
||||
if (l != 0)
|
||||
{
|
||||
fprintf(stderr, "close: returned %d\n", l);
|
||||
perror("The error was");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fd = open("/dev/zero", O_RDWR);
|
||||
v = (char *)mmap(0, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||
if (v == (char *)-1)
|
||||
{
|
||||
fprintf(stderr, "mmap r/w /dev/zero failed\n");
|
||||
perror("The error was");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (r=0; r<65536; r++)
|
||||
if (v[r] != 0)
|
||||
{
|
||||
fprintf(stderr, "mmap'd r/w /dev/zero has byte %d at offset %d\n",
|
||||
v[r], r);
|
||||
exit(1);
|
||||
}
|
||||
munmap(v, 65536);
|
||||
close(fd);
|
||||
|
||||
fd = open("/dev/zero", O_RDONLY);
|
||||
v = (char *)mmap(0, 65536, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (v == (char *)-1)
|
||||
{
|
||||
fprintf(stderr, "mmap /dev/zero r/o failed\n");
|
||||
perror("The error was");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (r=0; r<65536; r++)
|
||||
if (v[r] != 0)
|
||||
{
|
||||
fprintf(stderr, "mmap'd r/o /dev/zero has byte %d at offset %d\n",
|
||||
v[r], r);
|
||||
exit(1);
|
||||
}
|
||||
munmap(v, 65536);
|
||||
close(fd);
|
||||
|
||||
exit(0);
|
||||
}
|
4
winsup/cygwin/testsuite/winsup.api/samples/sample-pass.c
Normal file
4
winsup/cygwin/testsuite/winsup.api/samples/sample-pass.c
Normal file
@ -0,0 +1,4 @@
|
||||
main()
|
||||
{
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
main()
|
||||
{
|
||||
return 1;
|
||||
}
|
@ -0,0 +1 @@
|
||||
foo bar grill
|
43
winsup/cygwin/testsuite/winsup.api/winsup.exp
Normal file
43
winsup/cygwin/testsuite/winsup.api/winsup.exp
Normal file
@ -0,0 +1,43 @@
|
||||
source "site.exp"
|
||||
|
||||
if { ! [isnative] } {
|
||||
verbose "skipping winsup.api because it's not native"
|
||||
return
|
||||
}
|
||||
|
||||
set rv ""
|
||||
|
||||
proc ws_spawn {cmd args} {
|
||||
global rv
|
||||
verbose "running $cmd\n"
|
||||
catch [eval "exec $cmd"] rv
|
||||
verbose send "catchCode = $rv\n"
|
||||
}
|
||||
|
||||
foreach src [glob -nocomplain $srcdir/$subdir/*.c $srcdir/$subdir/*/*.c] {
|
||||
regsub "^$srcdir/$subdir/" $src "" testcase
|
||||
regsub ".c$" $testcase "" base
|
||||
regsub ".*/" $base "" basename
|
||||
regsub "/" $base "-" base
|
||||
|
||||
if { [regexp "^xf-" $basename] } {
|
||||
setup_xfail "*-*-*"
|
||||
} else {
|
||||
clear_xfail
|
||||
}
|
||||
|
||||
ws_spawn "$CC $src $rootme/new-libcygwin.a -o $base.exe"
|
||||
if { $rv != "" } {
|
||||
verbose -log "$rv"
|
||||
fail "$testcase (compile)"
|
||||
} else {
|
||||
ws_spawn "../cygrun ./$base.exe"
|
||||
if { $rv != "" } {
|
||||
verbose -log "$testcase: $rv"
|
||||
fail "$testcase (execute)"
|
||||
} else {
|
||||
pass "$testcase"
|
||||
file delete "$base.exe"
|
||||
}
|
||||
}
|
||||
}
|
83
winsup/doc/sites.texinfo
Normal file
83
winsup/doc/sites.texinfo
Normal file
@ -0,0 +1,83 @@
|
||||
@chapter Cygwin Resources on the Internet
|
||||
|
||||
@section FTP Sites
|
||||
|
||||
@itemize @bullet
|
||||
@item North America:
|
||||
@itemize @bullet
|
||||
@item Alberta: @file{ftp://ftp.reversion.ca/pub/mirrors/cygwin/}
|
||||
@item Arizona: @file{ftp://ftp.ninemoons.com/pub/cygwin/}
|
||||
@item California: @file{ftp://ftp.yggdrasil.com/mirrors/site/sourceware.cygnus.com/pub/cygwin/}
|
||||
@item California (secondary): @file{ftp://sourceware.cygnus.com/pub/cygwin/}
|
||||
@item Kansas: @file{ftp://ftp.the-b.org/pub/cygwin/}
|
||||
@item Tennessee: @file{ftp://ftp.sunsite.utk.edu/pub/cygwin/}
|
||||
@end itemize
|
||||
|
||||
@item Central America:
|
||||
@itemize @bullet
|
||||
@item Costa Rica: @file{ftp://sunsite.ulatina.ac.cr/cygwin/}
|
||||
@end itemize
|
||||
|
||||
@item South America:
|
||||
@itemize @bullet
|
||||
@item Brazil: @file{ftp://ftp.unicamp.br/pub/gnu/=EXTRA=/cygnus/cygwin/}
|
||||
@end itemize
|
||||
|
||||
@item Africa:
|
||||
@itemize @bullet
|
||||
@item South Africa: @file{ftp://ftp.sun.ac.za/sites/sourceware.cygnus.com/pub/cygwin/}
|
||||
@end itemize
|
||||
|
||||
@item Asia:
|
||||
@itemize @bullet
|
||||
@item Japan: @file{ftp://ring.aist.go.jp/archives/pc/gnu-win32/}
|
||||
@item Japan: @file{ftp://ring.etl.go.jp/archives/pc/gnu-win32/}
|
||||
@item Japan: @file{ftp://ring.asahi-net.or.jp/archives/pc/gnu-win32/}
|
||||
@item Japan: @file{ftp://ring.crl.go.jp/archives/pc/gnu-win32/}
|
||||
@item Japan: @file{ftp://ring.astem.or.jp/archives/pc/gnu-win32/}
|
||||
@item Japan: @file{ftp://ring.jah.ne.jp/archives/pc/gnu-win32/}
|
||||
@item Japan: @file{ftp://ring.saitama-u.ac.jp/archives/pc/gnu-win32/}
|
||||
@item Japan: @file{ftp://ring.nacsis.ac.jp/archives/pc/gnu-win32/}
|
||||
@item Japan: @file{ftp://ring.exp.fujixerox.co.jp/archives/pc/gnu-win32/}
|
||||
@item Japan: @file{ftp://ring.so-net.ne.jp/archives/pc/gnu-win32/}
|
||||
@item Japan: @file{ftp://ring.ip-kyoto.ad.jp/archives/pc/gnu-win32/}
|
||||
@item Japan: @file{ftp://sysg.kek.jp/cygnus/cygwin/}
|
||||
@item Japan: @file{ftp://ftp.u-aizu.ac.jp/pub/gnu/gnu-win32/}
|
||||
@item Taiwan: @file{ftp://ftp1.sinica.edu.tw/pub3/CYGNUS/cygwin/}
|
||||
@end itemize
|
||||
|
||||
@item Australasia:
|
||||
@itemize @bullet
|
||||
@item Australia: @file{ftp://mirror.aarnet.edu.au/pub/cygwin/}
|
||||
@end itemize
|
||||
|
||||
@item Europe:
|
||||
@itemize @bullet
|
||||
@item Austria: @file{ftp://gd.tuwien.ac.at/gnu/cygwin/}
|
||||
@item Czech Republic: @file{ftp://sunsite.ms.mff.cuni.cz/MIRRORS/sourceware.cygnus.com/pub/cygwin/}
|
||||
@item Denmark: @file{ftp://sunsite.auc.dk/pub/cygwin/}
|
||||
@item Finland: @file{ftp://ftp.funet.fi/mirrors/sourceware.cygnus.com/pub/cygwin/}
|
||||
@item Germany: @file{ftp://ftp.franken.de/pub/win32/develop/gnuwin32/cygwin32/mirrors/cygnus/}
|
||||
@item Greece: @file{ftp://ftp.ntua.gr/pub/pc/cygwin/}
|
||||
@item Hungary: @file{ftp://ftp.szrmkk.hu/pub/gnu-win32/ftp.cygnus.com/}
|
||||
@item Italy: @file{ftp://ftp.unina.it/pub/Unix/cygnus/cygwin/}
|
||||
@item Poland: @file{ftp://sunsite.icm.edu.pl/pub/cygnus/cygwin/}
|
||||
@item Slovenia: @file{ftp://sunsite.fri.uni-lj.si/pub/gnu-win32/}
|
||||
@item Spain: @file{ftp://ftp.rediris.es/mirror/cygwin}
|
||||
@item Sweden: @file{ftp://ftp.sunet.se/pub/lang/cygwin/}
|
||||
@item Switzerland: @file{ftp://sunsite.cnlab-switch.ch/mirror/cygwin/}
|
||||
@item UK: @file{ftp://sunsite.org.uk/Mirrors/sourceware.cygnus.com/pub/cygwin/}
|
||||
@item UK: @file{ftp://ftp.ccp14.dl.ac.uk/ccp14/ftp-mirror/programming/cygnus-gnu-win32/pub/gnu-win32/}
|
||||
@end itemize
|
||||
@end itemize
|
||||
|
||||
@section The Cygwin Project WWW Site
|
||||
|
||||
The main WWW page for the Cygwin project is
|
||||
@file{http://sourceware.cygnus.com/cygwin/}.
|
||||
|
||||
A page containing tool-specific information is
|
||||
@file{http://www.cygnus.com/pubs/gnupro/}.
|
||||
|
||||
Links to additional documentation are accessible from the main
|
||||
web page.
|
313
winsup/mingw/dirent.c
Normal file
313
winsup/mingw/dirent.c
Normal file
@ -0,0 +1,313 @@
|
||||
/*
|
||||
* dirent.c
|
||||
*
|
||||
* Derived from DIRLIB.C by Matt J. Weinstein
|
||||
* This note appears in the DIRLIB.H
|
||||
* DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
|
||||
*
|
||||
* Updated by Jeremy Bettis <jeremy@hksys.com>
|
||||
* Significantly revised and rewinddir, seekdir and telldir added by Colin
|
||||
* Peters <colin@fu.is.saga-u.ac.jp>
|
||||
*
|
||||
* $Revision$
|
||||
* $Author$
|
||||
* $Date$
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <io.h>
|
||||
#include <direct.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
#define SUFFIX "*"
|
||||
#define SLASH "\\"
|
||||
|
||||
/*
|
||||
* opendir
|
||||
*
|
||||
* Returns a pointer to a DIR structure appropriately filled in to begin
|
||||
* searching a directory.
|
||||
*/
|
||||
DIR *
|
||||
opendir (const char *szPath)
|
||||
{
|
||||
DIR *nd;
|
||||
struct _stat statDir;
|
||||
|
||||
errno = 0;
|
||||
|
||||
if (!szPath)
|
||||
{
|
||||
errno = EFAULT;
|
||||
return (DIR *) 0;
|
||||
}
|
||||
|
||||
if (szPath[0] == '\0')
|
||||
{
|
||||
errno = ENOTDIR;
|
||||
return (DIR *) 0;
|
||||
}
|
||||
|
||||
/* Attempt to determine if the given path really is a directory. */
|
||||
if (_stat (szPath, &statDir))
|
||||
{
|
||||
/* Error, stat should have set an error value. */
|
||||
return (DIR *) 0;
|
||||
}
|
||||
|
||||
if (!S_ISDIR (statDir.st_mode))
|
||||
{
|
||||
/* Error, stat reports not a directory. */
|
||||
errno = ENOTDIR;
|
||||
return (DIR *) 0;
|
||||
}
|
||||
|
||||
/* Allocate enough space to store DIR structure and the complete
|
||||
* directory path given. */
|
||||
nd = (DIR *) malloc (sizeof (DIR) + strlen (szPath) + strlen (SLASH) +
|
||||
strlen (SUFFIX));
|
||||
|
||||
if (!nd)
|
||||
{
|
||||
/* Error, out of memory. */
|
||||
errno = ENOMEM;
|
||||
return (DIR *) 0;
|
||||
}
|
||||
|
||||
/* Create the search expression. */
|
||||
strcpy (nd->dd_name, szPath);
|
||||
|
||||
/* Add on a slash if the path does not end with one. */
|
||||
if (nd->dd_name[0] != '\0' &&
|
||||
nd->dd_name[strlen (nd->dd_name) - 1] != '/' &&
|
||||
nd->dd_name[strlen (nd->dd_name) - 1] != '\\')
|
||||
{
|
||||
strcat (nd->dd_name, SLASH);
|
||||
}
|
||||
|
||||
/* Add on the search pattern */
|
||||
strcat (nd->dd_name, SUFFIX);
|
||||
|
||||
/* Initialize handle to -1 so that a premature closedir doesn't try
|
||||
* to call _findclose on it. */
|
||||
nd->dd_handle = -1;
|
||||
|
||||
/* Initialize the status. */
|
||||
nd->dd_stat = 0;
|
||||
|
||||
/* Initialize the dirent structure. ino and reclen are invalid under
|
||||
* Win32, and name simply points at the appropriate part of the
|
||||
* findfirst_t structure. */
|
||||
nd->dd_dir.d_ino = 0;
|
||||
nd->dd_dir.d_reclen = 0;
|
||||
nd->dd_dir.d_namlen = 0;
|
||||
nd->dd_dir.d_name = nd->dd_dta.name;
|
||||
|
||||
return nd;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* readdir
|
||||
*
|
||||
* Return a pointer to a dirent structure filled with the information on the
|
||||
* next entry in the directory.
|
||||
*/
|
||||
struct dirent *
|
||||
readdir (DIR * dirp)
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
/* Check for valid DIR struct. */
|
||||
if (!dirp)
|
||||
{
|
||||
errno = EFAULT;
|
||||
return (struct dirent *) 0;
|
||||
}
|
||||
|
||||
if (dirp->dd_dir.d_name != dirp->dd_dta.name)
|
||||
{
|
||||
/* The structure does not seem to be set up correctly. */
|
||||
errno = EINVAL;
|
||||
return (struct dirent *) 0;
|
||||
}
|
||||
|
||||
if (dirp->dd_stat < 0)
|
||||
{
|
||||
/* We have already returned all files in the directory
|
||||
* (or the structure has an invalid dd_stat). */
|
||||
return (struct dirent *) 0;
|
||||
}
|
||||
else if (dirp->dd_stat == 0)
|
||||
{
|
||||
/* We haven't started the search yet. */
|
||||
/* Start the search */
|
||||
dirp->dd_handle = _findfirst (dirp->dd_name, &(dirp->dd_dta));
|
||||
|
||||
if (dirp->dd_handle == -1)
|
||||
{
|
||||
/* Whoops! Seems there are no files in that
|
||||
* directory. */
|
||||
dirp->dd_stat = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dirp->dd_stat = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the next search entry. */
|
||||
if (_findnext (dirp->dd_handle, &(dirp->dd_dta)))
|
||||
{
|
||||
/* We are off the end or otherwise error. */
|
||||
_findclose (dirp->dd_handle);
|
||||
dirp->dd_handle = -1;
|
||||
dirp->dd_stat = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the status to indicate the correct
|
||||
* number. */
|
||||
dirp->dd_stat++;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirp->dd_stat > 0)
|
||||
{
|
||||
/* Successfully got an entry. Everything about the file is
|
||||
* already appropriately filled in except the length of the
|
||||
* file name. */
|
||||
dirp->dd_dir.d_namlen = strlen (dirp->dd_dir.d_name);
|
||||
return &dirp->dd_dir;
|
||||
}
|
||||
|
||||
return (struct dirent *) 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* closedir
|
||||
*
|
||||
* Frees up resources allocated by opendir.
|
||||
*/
|
||||
int
|
||||
closedir (DIR * dirp)
|
||||
{
|
||||
int rc;
|
||||
|
||||
errno = 0;
|
||||
rc = 0;
|
||||
|
||||
if (!dirp)
|
||||
{
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dirp->dd_handle != -1)
|
||||
{
|
||||
rc = _findclose (dirp->dd_handle);
|
||||
}
|
||||
|
||||
/* Delete the dir structure. */
|
||||
free (dirp);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* rewinddir
|
||||
*
|
||||
* Return to the beginning of the directory "stream". We simply call findclose
|
||||
* and then reset things like an opendir.
|
||||
*/
|
||||
void
|
||||
rewinddir (DIR * dirp)
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
if (!dirp)
|
||||
{
|
||||
errno = EFAULT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (dirp->dd_handle != -1)
|
||||
{
|
||||
_findclose (dirp->dd_handle);
|
||||
}
|
||||
|
||||
dirp->dd_handle = -1;
|
||||
dirp->dd_stat = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* telldir
|
||||
*
|
||||
* Returns the "position" in the "directory stream" which can be used with
|
||||
* seekdir to go back to an old entry. We simply return the value in stat.
|
||||
*/
|
||||
long
|
||||
telldir (DIR * dirp)
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
if (!dirp)
|
||||
{
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
return dirp->dd_stat;
|
||||
}
|
||||
|
||||
/*
|
||||
* seekdir
|
||||
*
|
||||
* Seek to an entry previously returned by telldir. We rewind the directory
|
||||
* and call readdir repeatedly until either dd_stat is the position number
|
||||
* or -1 (off the end). This is not perfect, in that the directory may
|
||||
* have changed while we weren't looking. But that is probably the case with
|
||||
* any such system.
|
||||
*/
|
||||
void
|
||||
seekdir (DIR * dirp, long lPos)
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
if (!dirp)
|
||||
{
|
||||
errno = EFAULT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (lPos < -1)
|
||||
{
|
||||
/* Seeking to an invalid position. */
|
||||
errno = EINVAL;
|
||||
return;
|
||||
}
|
||||
else if (lPos == -1)
|
||||
{
|
||||
/* Seek past end. */
|
||||
if (dirp->dd_handle != -1)
|
||||
{
|
||||
_findclose (dirp->dd_handle);
|
||||
}
|
||||
dirp->dd_handle = -1;
|
||||
dirp->dd_stat = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Rewind and read forward to the appropriate index. */
|
||||
rewinddir (dirp);
|
||||
|
||||
while ((dirp->dd_stat < lPos) && readdir (dirp))
|
||||
;
|
||||
}
|
||||
}
|
25
winsup/mingw/profile/ChangeLog
Normal file
25
winsup/mingw/profile/ChangeLog
Normal file
@ -0,0 +1,25 @@
|
||||
Thu Nov 18 00:20:00 1999 Mumit Khan <khan@xraylith.wisc.edu>
|
||||
|
||||
* profil.c (profile_on): Set the profiler thread priority to
|
||||
be time critical. Thanks to Pascal Obry <pascal_obry@csi.com>.
|
||||
|
||||
Sun Nov 7 04:17:27 1999 Mumit Khan <khan@xraylith.wisc.edu>
|
||||
|
||||
* Makefile.in (install): Fix target.
|
||||
|
||||
Thu Nov 4 14:06:21 1999 Mumit Khan <khan@xraylith.wisc.edu>
|
||||
|
||||
* Makefile.in: New file.
|
||||
* configure.in: New file.
|
||||
* configure: Generate.
|
||||
|
||||
* gcrt0.c (u_char, u_short, u_int, u_long): typedef for Mingw.
|
||||
* gmon.h (u_char, u_short, u_int, u_long): Likewise.
|
||||
* gmon.c (unistd.h): Include conditionally.
|
||||
(sys/param.h): Likewise.
|
||||
* mcount.c (sys/param.h): Likewise.
|
||||
* profil.c (profile_on): thread id is DWORD, not int.
|
||||
|
||||
* Imported profiling sources from winsup-19991026 snapshot.
|
||||
|
||||
|
126
winsup/utils/cygwin.cc
Normal file
126
winsup/utils/cygwin.cc
Normal file
@ -0,0 +1,126 @@
|
||||
/* cygwin.cc: general system debugging tool.
|
||||
|
||||
Copyright 1996, 1998 Cygnus Solutions.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
/* This program is intended to be a general tool for debugging cygwin.
|
||||
Possibilities include
|
||||
- dumping various internal data structures
|
||||
- poking various values into system tables
|
||||
- turning on strace'ing for arbitrary tasks
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <windows.h>
|
||||
#include "winsup.h"
|
||||
|
||||
static char *prog_name;
|
||||
|
||||
static void
|
||||
usage (FILE *stream, int status)
|
||||
{
|
||||
fprintf (stream, "\
|
||||
Usage: %s \\\n\
|
||||
[-s|--strace pid mask]\\\n\
|
||||
[-H|--help] [-V|--version]\n\
|
||||
",
|
||||
prog_name);
|
||||
exit (status);
|
||||
}
|
||||
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "help", no_argument, NULL, 'H' },
|
||||
{ "strace", required_argument, NULL, 's' },
|
||||
{ 0, no_argument, 0, 0 }
|
||||
};
|
||||
|
||||
struct strace_args
|
||||
{
|
||||
int pid;
|
||||
int mask;
|
||||
char *fn;
|
||||
};
|
||||
|
||||
/* Turn on strace'ing for the indicated pid. */
|
||||
|
||||
static void
|
||||
set_strace (strace_args *args)
|
||||
{
|
||||
shared_info *s = cygwin_getshared ();
|
||||
|
||||
pinfo *p = s->p[args->pid];
|
||||
|
||||
if (!p)
|
||||
{
|
||||
fprintf (stderr, "%s: process %d not found\n", prog_name, args->pid);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
p->strace_mask = args->mask;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int c;
|
||||
int seen_flag_p = 0;
|
||||
int show_version_p = 0;
|
||||
int set_strace_p = 0;
|
||||
strace_args strace_args;
|
||||
|
||||
prog_name = strrchr (argv[0], '/');
|
||||
if (prog_name == NULL)
|
||||
prog_name = strrchr (argv[0], '\\');
|
||||
if (prog_name == NULL)
|
||||
prog_name = argv[0];
|
||||
|
||||
while ((c = getopt_long (argc, argv, "HVs:", long_options, (int *) 0))
|
||||
!= EOF)
|
||||
{
|
||||
seen_flag_p = 1;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'H':
|
||||
usage (stdout, 0);
|
||||
break;
|
||||
case 'V':
|
||||
show_version_p = 1;
|
||||
break;
|
||||
case 's':
|
||||
if (optind + 1 > argc)
|
||||
usage (stderr, 1);
|
||||
strace_args.pid = atoi (optarg);
|
||||
if (optind < argc)
|
||||
strace_args.mask = atoi (argv[optind++]);
|
||||
if (optind < argc)
|
||||
strace_args.fn = argv[optind++];
|
||||
set_strace_p = 1;
|
||||
break;
|
||||
default:
|
||||
usage (stderr, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (show_version_p)
|
||||
printf ("CYGWIN version ???\n");
|
||||
|
||||
if (!seen_flag_p || optind != argc)
|
||||
usage (stderr, 1);
|
||||
|
||||
if (set_strace_p)
|
||||
set_strace (&strace_args);
|
||||
|
||||
return 0;
|
||||
}
|
91
winsup/w32api/README
Normal file
91
winsup/w32api/README
Normal file
@ -0,0 +1,91 @@
|
||||
Free headers and libraries for the Win32 API
|
||||
|
||||
Written by Anders Norlander
|
||||
Send bug reports and questions to anorland@hem2.passagen.se
|
||||
URL: http://www.acc.umu.se/~anorland/gnu-win32/
|
||||
|
||||
* License
|
||||
|
||||
You are free to use, modify and copy this package. No restrictions
|
||||
are imposed on programs or object files compiled with this library.
|
||||
|
||||
You may not restrict the the usage of this library.
|
||||
|
||||
You may distribute this library as part of another package or as a
|
||||
modified package if and only if you do *not* restrict the usage of
|
||||
the portions consisting of this (optionally modified) library.
|
||||
|
||||
If distributed as part of another package, please notify the author
|
||||
of what you are going to do. If distributed as a modified package,
|
||||
this file *must* be included.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
* What is it?
|
||||
|
||||
This is a free set of headers and import libraries for the Win32
|
||||
API. The library differs from the GNU Windows32 library in that I
|
||||
have tried to use a file structure that mirrors Microsoft's. I
|
||||
don't like having *all* definitions in one single header as in the
|
||||
GNU Windows32 library, I want a clean separation between different
|
||||
parts of the API.
|
||||
|
||||
Daniel Guerrero Miralles contributed the DirectX 6.1 import
|
||||
libraries and DirectX GUID definitions.
|
||||
|
||||
See the files NOTES and TODO for what needs to be done.
|
||||
|
||||
* Size does matter
|
||||
|
||||
Since the WIN32 API is severely bloated (as most MS products seem to
|
||||
be) the headers are designed to be as compact as possible, while
|
||||
still being readable, in order to minimize parsing time.
|
||||
|
||||
The convention is to omit parameter names for function prototypes,
|
||||
no excessive white space. Struct/union members are indented with tab
|
||||
characters to make them readable. Comment only when necessary.
|
||||
|
||||
If you are contributing a patch please follow the above mentioned
|
||||
convention. Make sure your editor does not convert tabs to spaces.
|
||||
|
||||
* What do I need to use it?
|
||||
|
||||
The library is intended for use with egcs 1.1 or later but it is
|
||||
possible to use with some other tools as well (although it is not
|
||||
very useful). LCC-Win32, MSVC and Borland C++ 5.01 or higher may
|
||||
work as well. The import libraries are for GNU tools only.
|
||||
|
||||
The library requires egcs 1.1 or later, since the `#pragma pack'
|
||||
feature is used. Mumit Khan provides egcs patches and binaries for
|
||||
win32 at `http://www.xraylith.wisc.edu/~khan/software/gnu-win32/'.
|
||||
|
||||
If you are going to use C++ COM objects, you will need a version of
|
||||
egcs that recognizes the `comobject' attribute and then define
|
||||
HAVE_COMOBJECT when compiling your program. Antonio Mendes de
|
||||
Oliveira Neto has a prebuilt version at
|
||||
`http://li.facens.br/EGCS-WIN32/english/index.html'. Note that this
|
||||
is very experimental. If you want to use COM objects in C++ but with
|
||||
C interfaces you must define CINTERFACE.
|
||||
|
||||
Objective-C programs cannot use COM functionality because of
|
||||
conflicts between the interface define and the Objective-C
|
||||
@interface directive. There is also a conflict between the windows
|
||||
Obj-C BOOL types. To avoid this conflict you should use WINBOOL in
|
||||
all places where you would use BOOL in a C/C++ windows program. If
|
||||
you include any windows headers *after* `windows.h' you must use the
|
||||
method outlined below:
|
||||
|
||||
/* non-windows includes */
|
||||
#include <objc/objc.h>
|
||||
...
|
||||
/* windows specific headers */
|
||||
#include <windows.h>
|
||||
#define BOOL WINBOOL
|
||||
#include <commctrl.h>
|
||||
...
|
||||
#undef BOOL
|
||||
...
|
||||
/* include other headers */
|
||||
|
17
winsup/w32api/include/excpt.h
Normal file
17
winsup/w32api/include/excpt.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef _EXCPT_H
|
||||
#define _EXCPT_H
|
||||
|
||||
/* FIXME: This will make some code compile. The programs will most
|
||||
likely crash when an exception is raised, but at least they will
|
||||
compile. */
|
||||
#ifdef __GNUC__
|
||||
#define __try
|
||||
#define __except(x) if (0) /* don't execute handler */
|
||||
#define __finally
|
||||
|
||||
#define _try __try
|
||||
#define _except __except
|
||||
#define _finally __finally
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user