4
0
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:
Christopher Faylor 2000-02-17 19:38:31 +00:00
parent 4415a7ef3e
commit 369d8a8fd5
31 changed files with 6439 additions and 0 deletions

76
winsup/cygwin/autoload.h Normal file
View 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
View 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;
}

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

View File

@ -0,0 +1 @@
/* ip.h */

View 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 */

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

File diff suppressed because it is too large Load Diff

View 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 */
}

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

File diff suppressed because it is too large Load Diff

View 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
View 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
View 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 ()
{
}

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

View File

@ -0,0 +1,6 @@
proc winsup_version {} {
clone_output "\n[exec grep ^%%% ../new-cygwin1.dll]\n"
}
proc winsup_exit {} {
}

View 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);
}

View File

@ -0,0 +1,4 @@
main()
{
return 0;
}

View File

@ -0,0 +1,4 @@
main()
{
return 1;
}

View File

@ -0,0 +1 @@
foo bar grill

View 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
View 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
View 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))
;
}
}

View 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
View 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
View 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 */

View 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