* Makefile.in: Add cygheap.o.

* child_info.h: Add specific exec class.
* cygheap.h: New file.  Contains declarations for cygwin heap.
* cygheap.cc: New file.  Implements cygwin heap functions.
* dcrt0.cc (quoted): Simplify due to new method for passing arguments between
cygwin programs.
(alloc_stack_hard_way): Attempt to handle overlapped stack.
(dll_crt0_1): Move child_info processing here.  Accomodate new method for
passing arguments between cygwin programs.  Initialize cygwin heap.  Establish
__argc and __argv variables.
(_dll_crt0): Move most of child_info processing to dll_crt0_1.
(cygwin_dll_init): Remove duplication.
* dtable.cc (dtable::extend): Allocate dtable using cygwin heap.
(dtable::build_fhandler): Ditto for fhandler type being constructed.
(dtable::dup_worker): Free new fhandler from cygwin heap on error.
(dtable::select_*): Don't assume that this == fdtab.
(dtable::linearize_fd_array): Delete.
(dtable::delinearize_fd_array): Delete.
(dtable::fixup_after_exec): New file.
(dtable::vfork_child_dup): Use cygwin heap.
(dtable::vfork_parent_restore): Ditto.
* dtable.h: Remove obsolete methods.  Add new method.
* environ.cc (posify): Eliminate already_posix parameter and logic.
(envsize): New function.
(_addenv): Use envsize.
(environ_init): Accept an argument pointing to an existing environment list.
If supplied, allocate space for this in the the program's heap.
* fhandler.cc (fhandler_base::operator =): Move here from fhandler.h.  Use
cygwin heap to allocate filenames.
(fhandler_base::set_name): Allocate/free names from cygwin heap.
(fhandler_base::linearize): Delete.
(fhandler_base::de_linearize): Delete.
(fhandler_base::operator delete): Free from cygwin heap.
(fhandler_base::~fhandler_base): Ditto.
* fhandler.h: Accomodate elimination of *linearize and other changes above.
* fhandler_console.cc (fhandler_console::fixup_after_exec): Rename from
de_linearize.
* heap.h: New file.
* fhandler_tty.cc (fhandler_tty_slave::fhandler_tty_slave): Use cygwin heap for
name.  fhandler_tty::fixup_after_exec): Rename from de_linearize.
* fork.cc (fork): Call cygheap_fixup_in_child.
* heap.cc: Use declarations in heap.h.
* malloc.cc: Sprinkle assertions throughout to catch attempts to free/realloc
something from the cygwin heap.
* path.cc: Throughout, eliminate use of per-thread cache for cwd.  Use cwd_*
functions rather than cwd_* variables to access cwd_win32 and cwd_posix.
(cwd_win32): New function.
(cwd_posix): New function.
(cwd_hash): New function.
(cwd_fixup_after_exec): New function.
* path.h: Accomodate path.cc changes.
* pinfo.cc (pinfo_init): Accept a pointer to an environment table.  Pass this
to environ_init.  Eliminate old 'title' tests.
* pinfo.h: Accomodate above change in argument.
* spawn.cc (struct av): New method for building argv list.
(av::unshift): New method.
(spawn_guts): Allocate everything that the child process needs in the cygwin
heap and pass a pointer to this to the child.  Build argv list using new
method.  Eliminate delinearize stuff.
* thread.h: Eliminate _cwd_win32 and _cwd_posix buffers.
* winsup.h: Eliminate obsolete functions.  Add envsize() declaration.
This commit is contained in:
Christopher Faylor 2000-09-03 04:16:35 +00:00
parent 39630fe3a1
commit b0e82b74fb
44 changed files with 2219 additions and 1888 deletions

View File

@ -1,3 +1,70 @@
Sun Sep 3 00:07:32 2000 Christopher Faylor <cgf@cygnus.com>
* Makefile.in: Add cygheap.o.
* child_info.h: Add specific exec class.
* cygheap.h: New file. Contains declarations for cygwin heap.
* cygheap.cc: New file. Implements cygwin heap functions.
* dcrt0.cc (quoted): Simplify due to new method for passing arguments
between cygwin programs.
(alloc_stack_hard_way): Attempt to handle overlapped stack.
(dll_crt0_1): Move child_info processing here. Accomodate new method
for passing arguments between cygwin programs. Initialize cygwin heap.
Establish __argc and __argv variables.
(_dll_crt0): Move most of child_info processing to dll_crt0_1.
(cygwin_dll_init): Remove duplication.
* dtable.cc (dtable::extend): Allocate dtable using cygwin heap.
(dtable::build_fhandler): Ditto for fhandler type being constructed.
(dtable::dup_worker): Free new fhandler from cygwin heap on error.
(dtable::select_*): Don't assume that this == fdtab.
(dtable::linearize_fd_array): Delete.
(dtable::delinearize_fd_array): Delete.
(dtable::fixup_after_exec): New file.
(dtable::vfork_child_dup): Use cygwin heap.
(dtable::vfork_parent_restore): Ditto.
* dtable.h: Remove obsolete methods. Add new method.
* environ.cc (posify): Eliminate already_posix parameter and logic.
(envsize): New function.
(_addenv): Use envsize.
(environ_init): Accept an argument pointing to an existing environment
list. If supplied, allocate space for this in the the program's heap.
* fhandler.cc (fhandler_base::operator =): Move here from fhandler.h.
Use cygwin heap to allocate filenames.
(fhandler_base::set_name): Allocate/free names from cygwin heap.
(fhandler_base::linearize): Delete.
(fhandler_base::de_linearize): Delete.
(fhandler_base::operator delete): Free from cygwin heap.
(fhandler_base::~fhandler_base): Ditto.
* fhandler.h: Accomodate elimination of *linearize and other changes
above.
* fhandler_console.cc (fhandler_console::fixup_after_exec): Rename from
de_linearize.
* heap.h: New file.
* fhandler_tty.cc (fhandler_tty_slave::fhandler_tty_slave): Use cygwin
heap for name. fhandler_tty::fixup_after_exec): Rename from
de_linearize.
* fork.cc (fork): Call cygheap_fixup_in_child.
* heap.cc: Use declarations in heap.h.
* malloc.cc: Sprinkle assertions throughout to catch attempts to
free/realloc something from the cygwin heap.
* path.cc: Throughout, eliminate use of per-thread cache for cwd. Use
cwd_* functions rather than cwd_* variables to access cwd_win32 and
cwd_posix.
(cwd_win32): New function.
(cwd_posix): New function.
(cwd_hash): New function.
(cwd_fixup_after_exec): New function.
* path.h: Accomodate path.cc changes.
* pinfo.cc (pinfo_init): Accept a pointer to an environment table.
Pass this to environ_init. Eliminate old 'title' tests.
* pinfo.h: Accomodate above change in argument.
* spawn.cc (struct av): New method for building argv list.
(av::unshift): New method.
(spawn_guts): Allocate everything that the child process needs in the
cygwin heap and pass a pointer to this to the child. Build argv list
using new method. Eliminate delinearize stuff.
* thread.h: Eliminate _cwd_win32 and _cwd_posix buffers.
* winsup.h: Eliminate obsolete functions. Add envsize() declaration.
2000-09-02 Egor Duda <deo@logos-m.ru>
* Makefile.in: Remove "make check" support. It is now in

View File

@ -50,7 +50,7 @@ DEFS = @DEFS@
CC:=@CC@
# FIXME: Which is it, CC or CC_FOR_TARGET?
CC_FOR_TARGET:=$(CC)
CFLAGS:=@CFLAGS@ -MD
CFLAGS:=@CFLAGS@ -MD -fno-implement-inlines
CXXFLAGS:=@CXXFLAGS@
# For linking mount, etc. crt0.o isn't accessable in a fresh build.
@ -116,16 +116,17 @@ EXTRA_OFILES=$(bupdir1)/libiberty/random.o $(bupdir1)/libiberty/strsignal.o
DLL_IMPORTS:=$(w32api_lib)/libkernel32.a
DLL_OFILES:=assert.o dcrt0.o debug.o delqueue.o dir.o dlfcn.o dll_init.o \
dtable.o environ.o errno.o exceptions.o exec.o external.o fcntl.o \
fhandler.o fhandler_console.o fhandler_floppy.o fhandler_random.o \
fhandler_raw.o fhandler_serial.o fhandler_tape.o fhandler_termios.o \
fhandler_tty.o fhandler_windows.o fhandler_zero.o fork.o glob.o grp.o \
heap.o init.o ioctl.o localtime.o malloc.o mmap.o net.o ntea.o passwd.o \
path.o pinfo.o pipe.o poll.o regexp.o regerror.o regsub.o registry.o \
resource.o scandir.o security.o select.o shared.o signal.o sigproc.o \
smallprint.o spawn.o strace.o strsep.o sync.o syscalls.o sysconf.o \
syslog.o termios.o times.o tty.o uinfo.o uname.o wait.o window.o \
DLL_OFILES:=assert.o cygheap.o dcrt0.o debug.o delqueue.o dir.o dlfcn.o \
dll_init.o dtable.o environ.o errno.o exceptions.o exec.o external.o \
fcntl.o fhandler.o fhandler_console.o fhandler_floppy.o \
fhandler_random.o fhandler_raw.o fhandler_serial.o fhandler_tape.o \
fhandler_termios.o fhandler_tty.o fhandler_windows.o fhandler_zero.o \
fork.o glob.o grp.o heap.o init.o ioctl.o localtime.o malloc.o mmap.o \
net.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o regexp.o regerror.o \
regsub.o registry.o resource.o scandir.o security.o select.o shared.o \
signal.o sigproc.o smallprint.o spawn.o strace.o strsep.o sync.o \
syscalls.o sysconf.o syslog.o termios.o times.o tty.o uinfo.o uname.o \
wait.o window.o \
$(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MT_SAFE_OBJECTS)
GMON_OFILES:= gmon.o mcount.o profil.o

View File

@ -42,10 +42,10 @@ __assert (const char *file, int line, const char *failedexpr)
{
CloseHandle (h);
small_printf ("assertion \"%s\" failed: file \"%s\", line %d\n",
failedexpr, file, line);
failedexpr, file, line);
}
abort ();
abort (); // FIXME: Someday this should work.
/* NOTREACHED */
}

View File

@ -14,8 +14,9 @@ enum
PROC_FORK = PROC_MAGIC + 1,
PROC_EXEC = PROC_MAGIC + 2,
PROC_SPAWN = PROC_MAGIC + 3,
PROC_FORK1 = PROC_MAGIC + 4 // Newer versions provide stack
PROC_FORK1 = PROC_MAGIC + 4, // Newer versions provide stack
// location information
PROC_SPAWN1 = PROC_MAGIC + 5
};
#define PROC_MAGIC_MASK 0xff00f000
@ -34,12 +35,6 @@ public:
HANDLE shared_h;
HANDLE console_h;
HANDLE parent_alive; // handle of thread used to track children
HANDLE myself_pinfo;
~child_info ()
{
if (myself_pinfo)
CloseHandle (myself_pinfo);
}
};
class child_info_fork: public child_info
@ -55,9 +50,53 @@ public:
void *stackbottom; // location of bottom of parent stack
};
class fhandler_base;
class cygheap_exec_info
{
public:
char *old_title;
fhandler_base **fds;
size_t nfds;
int argc;
char **argv;
char **environ;
HANDLE myself_pinfo;
char *cwd_posix;
char *cwd_win32;
DWORD cwd_hash;
};
class child_info_spawn: public child_info
{
public:
HANDLE parent;
void *cygheap;
void *cygheap_max;
cygheap_exec_info *moreinfo;
child_info_spawn (): parent (NULL), cygheap (NULL),
cygheap_max (NULL), moreinfo (NULL) {}
~child_info_spawn ()
{
if (parent)
CloseHandle (parent);
if (moreinfo)
{
if (moreinfo->old_title)
cfree (moreinfo->old_title);
if (moreinfo->environ)
{
for (char **e = moreinfo->environ; *e; e++)
cfree (*e);
cfree (moreinfo->environ);
}
CloseHandle (moreinfo->myself_pinfo);
cfree (moreinfo);
}
}
};
void __stdcall init_child_info (DWORD, child_info *, int, HANDLE);
extern child_info_fork *child_proc_info;
/* non-NULL if this process is a child of a cygwin process */
extern HANDLE parent_alive;

232
winsup/cygwin/cygheap.cc Normal file
View File

@ -0,0 +1,232 @@
/* cygheap.cc: Cygwin heap manager.
Copyright 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. */
#include "winsup.h"
#include <errno.h>
#include <fhandler.h>
#include <assert.h>
#include "cygheap.h"
#include "heap.h"
#include "cygerrno.h"
#define HEAP_START ((void *) 0x12010000)
inline static void
init_cheap ()
{
if (!VirtualAlloc (HEAP_START, CYGHEAPSIZE, MEM_RESERVE, PAGE_NOACCESS))
api_fatal ("Couldn't reserve space for child's heap, %E");
cygheap = cygheap_max = HEAP_START;
}
#define pagetrunc(x) ((void *) (((DWORD) (x)) & ~(4096 - 1)))
static void *__stdcall
_csbrk (int sbs)
{
void *lastheap;
if (!cygheap)
init_cheap ();
lastheap = cygheap_max;
(char *) cygheap_max += sbs;
void *heapalign = (void *) pagetrunc (lastheap);
int needalloc = sbs && ((heapalign == lastheap) || heapalign != pagetrunc (cygheap_max));
if (needalloc && !VirtualAlloc (lastheap, (DWORD) sbs, MEM_COMMIT, PAGE_READWRITE))
api_fatal ("couldn't commit memory for cygwin heap, %E");
return lastheap;
}
/* Copyright (C) 1997, 2000 DJ Delorie */
char *buckets[32] = {0};
int bucket2size[32] = {0};
static inline int
size2bucket (int size)
{
int rv = 0x1f;
int bit = ~0x10;
int i;
if (size < 4)
size = 4;
size = (size + 3) & ~3;
for (i = 0; i < 5; i++)
{
if (bucket2size[rv & bit] >= size)
rv &= bit;
bit >>= 1;
}
return rv;
}
static inline void
init_buckets ()
{
unsigned b;
for (b = 0; b < 32; b++)
bucket2size[b] = (1 << b);
}
static void *__stdcall
_cmalloc (int size)
{
char *rv;
int b;
if (bucket2size[0] == 0)
init_buckets ();
b = size2bucket (size);
if (buckets[b])
{
rv = buckets[b];
buckets[b] = *(char **) rv;
return rv;
}
size = bucket2size[b] + 4;
rv = (char *) _csbrk (size);
*(int *) rv = b;
rv += 4;
return rv;
}
static void __stdcall
_cfree (void *ptr)
{
int b = *(int *) ((char *) ptr - 4);
*(char **) ptr = buckets[b];
buckets[b] = (char *) ptr;
}
static void *__stdcall
_crealloc (void *ptr, int size)
{
char *newptr;
int oldsize = bucket2size[*(int *) ((char *) ptr - 4)];
if (size <= oldsize)
return ptr;
newptr = (char *) _cmalloc (size);
memcpy (newptr, ptr, oldsize);
_cfree (ptr);
return newptr;
}
/* End Copyright (C) 1997 DJ Delorie */
void *cygheap = NULL;
void *cygheap_max = NULL;
#define sizeof_cygheap(n) ((n) + sizeof(cygheap_entry))
struct cygheap_entry
{
cygheap_types type;
char data[0];
};
#define N ((cygheap_entry *) NULL)
#define tocygheap(s) ((cygheap_entry *) (((char *) (s)) - (int) (N->data)))
void
cygheap_init ()
{
if (!cygheap)
init_cheap ();
}
extern "C" void __stdcall
cygheap_fixup_in_child (HANDLE parent)
{
DWORD m, n;
n = (DWORD) cygheap_max - (DWORD) cygheap;
if (!VirtualAlloc (cygheap, CYGHEAPSIZE, MEM_RESERVE, PAGE_NOACCESS))
api_fatal ("Couldn't reserve space for child's heap, %E");
if (!VirtualAlloc (cygheap, n, MEM_COMMIT, PAGE_READWRITE))
api_fatal ("Couldn't allocate space for child's heap %p, size %d, %E",
cygheap, n);
m = 0;
n = (DWORD) pagetrunc (n + 4095);
if (!ReadProcessMemory (parent, cygheap, cygheap, n, &m) ||
m != n)
api_fatal ("Couldn't read parent's cygwin heap %d bytes != %d, %E",
n, m);
}
static void *__stdcall
creturn (cygheap_types x, cygheap_entry * c, int len)
{
if (!c)
{
__seterrno ();
return NULL;
}
c->type = x;
if (cygheap_max < ((char *) c + len))
cygheap_max = (char *) c + len;
return (void *) c->data;
}
extern "C" void *__stdcall
cmalloc (cygheap_types x, DWORD n)
{
cygheap_entry *c;
c = (cygheap_entry *) _cmalloc (sizeof_cygheap (n));
if (!c)
system_printf ("cmalloc returned NULL");
return creturn (x, c, n);
}
extern "C" void *__stdcall
crealloc (void *s, DWORD n)
{
if (s == NULL)
return cmalloc (HEAP_STR, n); // kludge
assert (!inheap (s));
cygheap_entry *c = tocygheap (s);
cygheap_types t = c->type;
c = (cygheap_entry *) _crealloc (c, sizeof_cygheap (n));
if (!c)
system_printf ("crealloc returned NULL");
return creturn (t, c, n);
}
extern "C" void __stdcall
cfree (void *s)
{
assert (!inheap (s));
(void) _cfree (tocygheap (s));
}
extern "C" void *__stdcall
ccalloc (cygheap_types x, DWORD n, DWORD size)
{
cygheap_entry *c;
c = (cygheap_entry *) _cmalloc (sizeof_cygheap (n * size));
if (c)
memset (c->data, 0, size);
if (!c)
system_printf ("ccalloc returned NULL");
return creturn (x, c, n);
}
extern "C" char *__stdcall
cstrdup (const char *s)
{
char *p = (char *) cmalloc (HEAP_STR, strlen (s) + 1);
if (!p)
return NULL;
strcpy (p, s);
return p;
}

37
winsup/cygwin/cygheap.h Normal file
View File

@ -0,0 +1,37 @@
/* cygheap.h: Cygwin heap manager.
Copyright 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 cfree
enum cygheap_types
{
HEAP_FHANDLER,
HEAP_STR,
HEAP_ARGV,
HEAP_EXEC,
HEAP_BUF
};
#define CYGHEAPSIZE ((1000 * sizeof (fhandler_union)) + (2 * 65536))
extern HANDLE cygheap;
extern HANDLE cygheap_max;
#define incygheap(s) (cygheap && ((char *) (s) >= (char *) cygheap) && ((char *) (s) <= ((char *) cygheap) + CYGHEAPSIZE))
void cygheap_init ();
extern "C" {
void __stdcall cfree (void *);
void __stdcall cygheap_fixup_in_child (HANDLE);
void *__stdcall cmalloc (cygheap_types, DWORD);
void *__stdcall crealloc (void *, DWORD);
void *__stdcall ccalloc (cygheap_types, DWORD, DWORD);
char *__stdcall cstrdup (const char *);
}

View File

@ -20,6 +20,8 @@ details. */
#include "sigproc.h"
#include "perthread.h"
#include "pinfo.h"
#include "cygheap.h"
#include "heap.h"
#include "cygerrno.h"
#include "fhandler.h"
#include "child_info.h"
@ -121,7 +123,7 @@ do_global_ctors (void (**in_pfunc)(), int force)
if (!force)
{
if (user_data->forkee || user_data->run_ctors_p)
return; // inherit constructed stuff from parent pid
return; // inherit constructed stuff from parent pid
user_data->run_ctors_p = 1;
}
@ -293,58 +295,38 @@ quoted (char *cmd, int winshell)
char *p;
char quote = *cmd;
/* If this is being run from a Windows shell then we have
to preserve quotes for globify to play with later. */
if (winshell)
if (!winshell)
{
while (*++cmd)
if ((p = strchr (cmd, quote)) == NULL)
{
cmd = strchr (cmd, '\0'); // no closing quote
break;
}
else if (p[1] == quote && p[-1] != '\\')
{
*p = '\\';
cmd = ++p; // a quoted quote
}
else
{
cmd = p + 1; // point to after end
break;
}
return cmd;
char *p;
strcpy (cmd, cmd + 1);
if ((p = strchr (cmd, quote)) != NULL)
strcpy (p, p + 1);
return p + 1;
}
/* When running as a child of a cygwin process, the quoted
characters should have been placed here by spawn_guts, so
we'll just pinch them out of the command string unless
they're quoted with a preceding \ */
p = cmd + 1;
while (*p)
{
if (*p == '\\' && p[1] == '\\')
{
strcpy (p, p + 1);
p++;
}
else if (*p != quote)
p++;
else if (p[-1] == '\\')
strcpy (p - 1, p);
else if (p[1] == quote)
{
strcpy (p, p + 1);
p++;
}
else
{
strcpy (p, p + 1);
break;
}
}
strcpy (cmd, cmd + 1);
return p - 1;
/* This must have been run from a Windows shell, so preserve
quotes for globify to play with later. */
while (*++cmd)
if ((p = strpbrk (cmd, "\\\"")) == NULL)
{
cmd = strchr (cmd, '\0'); // no closing quote
break;
}
else if (quote == '\'')
continue;
else if (*p == '\\')
cmd = ++p;
else if (p[1] == quote)
{
*p = '\\';
cmd = ++p; // a quoted quote
}
else
{
cmd = p + 1; // point to after end
break;
}
return cmd;
}
/* Perform a glob on word if it contains wildcard characters.
@ -494,7 +476,8 @@ build_argv (char *cmd, char **&argv, int &argc, int winshell)
}
argv[argc] = NULL;
debug_printf ("argv[%d] = '%s'\n", argc, argv[argc]);
debug_printf ("argc %d", argc);
}
/* sanity and sync check */
@ -532,22 +515,35 @@ check_sanity_and_sync (per_process *p)
}
static NO_COPY STARTUPINFO si;
# define ciresrv ((struct child_info_fork *)(si.lpReserved2))
# define fork_info ((struct child_info_fork *)(si.lpReserved2))
# define spawn_info ((struct child_info_spawn *)(si.lpReserved2))
child_info_fork NO_COPY *child_proc_info = NULL;
static MEMORY_BASIC_INFORMATION sm;
#define EBP 6
#define ESP 7
extern __inline__ void
// __inline__ void
extern void
alloc_stack_hard_way (child_info_fork *ci, volatile char *b)
{
void *new_stack_pointer;
MEMORY_BASIC_INFORMATION m;
void *newbase;
int newlen;
LPBYTE curbot = (LPBYTE) sm.BaseAddress + sm.RegionSize;
bool noguard;
if (!VirtualAlloc (ci->stacktop,
(DWORD) ci->stackbottom - (DWORD) ci->stacktop,
MEM_RESERVE, PAGE_NOACCESS))
if (ci->stacktop > (LPBYTE) sm.AllocationBase && ci->stacktop < curbot)
{
newbase = curbot;
newlen = (LPBYTE) ci->stackbottom - (LPBYTE) curbot;
noguard = 1;
}
else
{
newbase = ci->stacktop;
newlen = (DWORD) ci->stackbottom - (DWORD) ci->stacktop;
noguard = 0;
}
if (!VirtualAlloc (newbase, newlen, MEM_RESERVE, PAGE_NOACCESS))
api_fatal ("fork: can't reserve memory for stack %p - %p, %E",
ci->stacktop, ci->stackbottom);
@ -559,11 +555,14 @@ alloc_stack_hard_way (child_info_fork *ci, volatile char *b)
new_stack_pointer, ci->stacksize);
if (!VirtualQuery ((LPCVOID) new_stack_pointer, &m, sizeof m))
api_fatal ("fork: couldn't get new stack info, %E");
m.BaseAddress = (LPVOID)((DWORD)m.BaseAddress - 1);
if (!VirtualAlloc ((LPVOID) m.BaseAddress, 1, MEM_COMMIT,
PAGE_EXECUTE_READWRITE|PAGE_GUARD))
api_fatal ("fork: couldn't allocate new stack guard page %p, %E",
m.BaseAddress);
if (!noguard)
{
m.BaseAddress = (LPVOID)((DWORD)m.BaseAddress - 1);
if (!VirtualAlloc ((LPVOID) m.BaseAddress, 1, MEM_COMMIT,
PAGE_EXECUTE_READWRITE|PAGE_GUARD))
api_fatal ("fork: couldn't allocate new stack guard page %p, %E",
m.BaseAddress);
}
if (!VirtualQuery ((LPCVOID) m.BaseAddress, &m, sizeof m))
api_fatal ("fork: couldn't get new stack info, %E");
ci->stacktop = m.BaseAddress;
@ -572,7 +571,7 @@ alloc_stack_hard_way (child_info_fork *ci, volatile char *b)
/* extend the stack prior to fork longjmp */
extern __inline__ void
static void
alloc_stack (child_info_fork *ci)
{
/* FIXME: adding 16384 seems to avoid a stack copy problem during
@ -595,12 +594,9 @@ alloc_stack (child_info_fork *ci)
return;
}
/* These must be static due to the way we have to deal with forked
processes. */
static NO_COPY LPBYTE info = NULL;
static NO_COPY int mypid = 0;
static int argc = 0;
static char **argv = NULL;
int _declspec(dllexport) __argc = 0;
char _declspec(dllexport) **__argv = NULL;
void
sigthread::init (const char *s)
@ -616,22 +612,20 @@ sigthread::init (const char *s)
static void
dll_crt0_1 ()
{
#ifdef DEBUGGING
if (child_proc_info)
switch (child_proc_info->type)
{
case PROC_FORK:
case PROC_FORK1:
ProtectHandle (child_proc_info->forker_finished);
case PROC_EXEC:
ProtectHandle (child_proc_info->subproc_ready);
}
ProtectHandle (hMainProc);
ProtectHandle (hMainThread);
#endif
/* According to onno@stack.urc.tue.nl, the exception handler record must
be on the stack. */
/* FIXME: Verify forked children get their exception handler set up ok. */
exception_list cygwin_except_entry;
regthread ("main", GetCurrentThreadId ());
/* Initialize SIGSEGV handling, etc... Because the exception handler
references data in the shared area, this must be done after
shared_init. */
init_exceptions (&cygwin_except_entry);
do_global_ctors (&__CTOR_LIST__, 1);
/* Set the os_being_run global. */
set_os_type ();
check_sanity_and_sync (user_data);
/* Nasty static stuff needed by newlib -- point to a local copy of
@ -642,10 +636,58 @@ dll_crt0_1 ()
_impure_ptr = &reent_data;
#ifdef _MT_SAFE
user_data->resourcelocks->Init();
user_data->threadinterface->Init0();
#endif
user_data->resourcelocks->Init ();
user_data->threadinterface->Init0 ();
regthread ("main", GetCurrentThreadId ());
char **envp = NULL;
if (child_proc_info)
{
switch (child_proc_info->type)
{
case PROC_FORK:
case PROC_FORK1:
alloc_stack (fork_info);
set_myself (mypid);
user_data->forkee = child_proc_info->cygpid;
user_data->heaptop = child_proc_info->heaptop;
user_data->heapbase = child_proc_info->heapbase;
user_data->heapptr = child_proc_info->heapptr;
ProtectHandle (child_proc_info->forker_finished);
break;
case PROC_EXEC:
case PROC_SPAWN:
HANDLE h;
cygheap = spawn_info->cygheap;
cygheap_max = spawn_info->cygheap_max;
cygheap_fixup_in_child (spawn_info->parent);
if (!spawn_info->moreinfo->myself_pinfo ||
!DuplicateHandle (hMainProc, spawn_info->moreinfo->myself_pinfo,
hMainProc, &h, 0, 0,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
h = NULL;
set_myself (mypid, h);
__argc = spawn_info->moreinfo->argc;
__argv = spawn_info->moreinfo->argv;
envp = spawn_info->moreinfo->environ;
cwd_fixup_after_exec (spawn_info->moreinfo->cwd_win32,
spawn_info->moreinfo->cwd_posix,
spawn_info->moreinfo->cwd_hash);
fdtab.fixup_after_exec (spawn_info->parent, spawn_info->moreinfo->nfds,
spawn_info->moreinfo->fds);
CloseHandle (spawn_info->parent);
if (spawn_info->moreinfo->old_title)
{
old_title = strcpy (title_buf, spawn_info->moreinfo->old_title);
cfree (spawn_info->moreinfo->old_title);
}
ProtectHandle (child_proc_info->subproc_ready);
break;
}
}
ProtectHandle (hMainProc);
ProtectHandle (hMainThread);
/* Initialize the host dependent constants object. */
host_dependent.init ();
@ -657,9 +699,6 @@ dll_crt0_1 ()
mainthread.init ("mainthread"); // For use in determining if signals
// should be blocked.
if (mypid)
set_myself ((pid_t) mypid, NULL);
(void) SetErrorMode (SEM_FAILCRITICALERRORS);
/* Initialize the heap. */
@ -684,18 +723,20 @@ dll_crt0_1 ()
NOTE: Don't do anything that involves the stack until you've completed
this step. */
if (ciresrv->stacksize)
if (fork_info->stacksize)
{
asm ("movl %0,%%fs:4" : : "r" (ciresrv->stackbottom));
asm ("movl %0,%%fs:8" : : "r" (ciresrv->stacktop));
asm ("movl %0,%%fs:4" : : "r" (fork_info->stackbottom));
asm ("movl %0,%%fs:8" : : "r" (fork_info->stacktop));
}
longjmp (ciresrv->jmp, ciresrv->cygpid);
longjmp (fork_info->jmp, fork_info->cygpid);
}
/* Initialize our process table entry. Don't use the parent info for
dynamically loaded case. */
pinfo_init ((dynamically_loaded) ? NULL : info);
cygheap_init (); /* Initialize cygwin's heap */
cwd_init ();
/* Initialize our process table entry. */
pinfo_init (envp);
if (!old_title && GetConsoleTitle (title_buf, TITLESIZE))
old_title = title_buf;
@ -740,26 +781,32 @@ dll_crt0_1 ()
/* Set up standard fds in file descriptor table. */
stdio_init ();
if (user_data->premain[0])
for (unsigned int i = 0; i < PREMAIN_LEN / 2; i++)
user_data->premain[i] (argc, argv);
/* Scan the command line and build argv. Expand wildcards if not
called from another cygwin process. */
build_argv (line, argv, argc,
NOTSTATE (myself, PID_CYGPARENT) && allow_glob);
/* Convert argv[0] to posix rules if it's currently blatantly
win32 style. */
if ((strchr (argv[0], ':')) || (strchr (argv[0], '\\')))
if (!__argc)
{
char *new_argv0 = (char *) alloca (MAX_PATH);
cygwin_conv_to_posix_path (argv[0], new_argv0);
argv[0] = new_argv0;
/* Scan the command line and build argv. Expand wildcards if not
called from another cygwin process. */
build_argv (line, __argv, __argc,
NOTSTATE (myself, PID_CYGPARENT) && allow_glob);
/* Convert argv[0] to posix rules if it's currently blatantly
win32 style. */
if ((strchr (__argv[0], ':')) || (strchr (__argv[0], '\\')))
{
char *new_argv0 = (char *) alloca (MAX_PATH);
cygwin_conv_to_posix_path (__argv[0], new_argv0);
char *p = strchr (new_argv0, '\0') - 4;
if (p > new_argv0 && strcasematch (p, ".exe"))
*p = '\0';
__argv[0] = new_argv0;
}
}
if (user_data->premain[0])
for (unsigned int i = 0; i < PREMAIN_LEN / 2; i++)
user_data->premain[i] (__argc, __argv);
/* Set up __progname for getopt error call. */
__progname = argv[0];
__progname = __argv[0];
cygwin_finished_initializing = 1;
/* Call init of loaded dlls. */
@ -768,7 +815,7 @@ dll_crt0_1 ()
/* Execute any specified "premain" functions */
if (user_data->premain[PREMAIN_LEN / 2])
for (unsigned int i = PREMAIN_LEN / 2; i < PREMAIN_LEN; i++)
user_data->premain[i] (argc, argv);
user_data->premain[i] (__argc, __argv);
debug_printf ("user_data->main %p", user_data->main);
@ -785,8 +832,9 @@ dll_crt0_1 ()
set_errno (0);
MALLOC_CHECK;
if (user_data->main)
exit (user_data->main (argc, argv, *user_data->envptr));
exit (user_data->main (__argc, __argv, *user_data->envptr));
}
/* Wrap the real one, otherwise gdb gets confused about
@ -798,16 +846,7 @@ dll_crt0_1 ()
extern "C" void __stdcall
_dll_crt0 ()
{
char zeros[sizeof (ciresrv->zero)] = {0};
/* According to onno@stack.urc.tue.nl, the exception handler record must
be on the stack. */
/* FIXME: Verify forked children get their exception handler set up ok. */
exception_list cygwin_except_entry;
/* Initialize SIGSEGV handling, etc... Because the exception handler
references data in the shared area, this must be done after
shared_init. */
init_exceptions (&cygwin_except_entry);
do_global_ctors (&__CTOR_LIST__, 1);
char zeros[sizeof (fork_info->zero)] = {0};
/* Set the os_being_run global. */
set_os_type ();
@ -833,62 +872,35 @@ _dll_crt0 ()
DuplicateHandle (hMainProc, GetCurrentThread (), hMainProc,
&hMainThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
HANDLE h;
GetStartupInfo (&si);
if (si.cbReserved2 >= EXEC_MAGIC_SIZE &&
memcmp (ciresrv->zero, zeros, sizeof (zeros)) == 0)
memcmp (fork_info->zero, zeros, sizeof (zeros)) == 0)
{
switch (ciresrv->type)
switch (fork_info->type)
{
case PROC_EXEC:
case PROC_SPAWN:
case PROC_FORK:
case PROC_FORK1:
{
HANDLE me = hMainProc;
child_proc_info = ciresrv;
child_proc_info = fork_info;
mypid = child_proc_info->cygpid;
cygwin_shared_h = child_proc_info->shared_h;
console_shared_h = child_proc_info->console_h;
/* We don't want subprocesses to inherit this */
if (!dynamically_loaded)
{
if (!DuplicateHandle (me, child_proc_info->parent_alive,
me, &parent_alive, 0, 0,
if (dynamically_loaded)
parent_alive = NULL;
else if (!DuplicateHandle (hMainProc, child_proc_info->parent_alive,
hMainProc, &parent_alive, 0, 0,
DUPLICATE_SAME_ACCESS
| DUPLICATE_CLOSE_SOURCE))
system_printf ("parent_alive DuplicateHandle failed, %E");
}
else if (parent_alive)
parent_alive = NULL;
system_printf ("parent_alive DuplicateHandle failed, %E");
switch (child_proc_info->type)
{
case PROC_EXEC:
case PROC_SPAWN:
info = si.lpReserved2 + ciresrv->cb;
if (child_proc_info->myself_pinfo &&
DuplicateHandle (hMainProc, child_proc_info->myself_pinfo,
hMainProc, &h, 0, 0,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
{
set_myself (mypid, h);
mypid = 0;
}
break;
case PROC_FORK:
case PROC_FORK1:
user_data->forkee = child_proc_info->cygpid;
user_data->heaptop = child_proc_info->heaptop;
user_data->heapbase = child_proc_info->heapbase;
user_data->heapptr = child_proc_info->heapptr;
alloc_stack (ciresrv); // may never return
}
break;
}
default:
if ((ciresrv->type & PROC_MAGIC_MASK) == PROC_MAGIC_GENERIC)
if ((fork_info->type & PROC_MAGIC_MASK) == PROC_MAGIC_GENERIC)
api_fatal ("conflicting versions of cygwin1.dll detected. Use only the most recent version.\n");
}
}
@ -913,19 +925,6 @@ cygwin_dll_init ()
{
static char **envp;
static int _fmode;
/* According to onno@stack.urc.tue.nl, the exception handler record must
be on the stack. */
/* FIXME: Verify forked children get their exception handler set up ok. */
exception_list cygwin_except_entry;
/* Initialize SIGSEGV handling, etc... Because the exception handler
references data in the shared area, this must be done after
shared_init. */
init_exceptions (&cygwin_except_entry);
do_global_ctors (&__CTOR_LIST__, 1);
/* Set the os_being_run global. */
set_os_type ();
user_data->heapbase = user_data->heapptr = user_data->heaptop = NULL;
if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),

View File

@ -86,7 +86,7 @@ delqueue_list::process_queue ()
int res = GetLastError ();
empty = 0;
if (res == ERROR_SHARING_VIOLATION ||
(os_being_run != winNT && res == ERROR_ACCESS_DENIED))
(os_being_run != winNT && res == ERROR_ACCESS_DENIED))
{
/* File still inuse, that's ok */
syscall_printf ("Still using %s", name[i]);
@ -94,7 +94,7 @@ delqueue_list::process_queue ()
else
{
syscall_printf ("Hmm, don't know what to do with '%s', %E", name[i]);
inuse[i] = 0;
inuse[i] = 0;
}
}
}

View File

@ -75,7 +75,7 @@ opendir (const char *dirname)
}
if (stat (myself->rootlen ? dirname : real_dirname.get_win32 (),
&statbuf) == -1)
&statbuf) == -1)
goto failed;
if (!(statbuf.st_mode & S_IFDIR))
@ -296,7 +296,7 @@ mkdir (const char *dir, mode_t mode)
if (CreateDirectoryA (real_dir.get_win32 (), 0))
{
set_file_attribute (real_dir.has_acls (), real_dir.get_win32 (),
S_IFDIR | ((mode & 0777) & ~myself->umask));
S_IFDIR | ((mode & 0777) & ~myself->umask));
res = 0;
}
else
@ -324,18 +324,18 @@ rmdir (const char *dir)
if (RemoveDirectoryA (real_dir.get_win32 ()))
{
/* RemoveDirectory on a samba drive doesn't return an error if the
directory can't be removed because it's not empty. Checking for
existence afterwards keeps us informed about success. */
directory can't be removed because it's not empty. Checking for
existence afterwards keeps us informed about success. */
if (GetFileAttributesA (real_dir.get_win32 ()) != (DWORD) -1)
set_errno (ENOTEMPTY);
set_errno (ENOTEMPTY);
else
res = 0;
res = 0;
}
else if (GetLastError() == ERROR_ACCESS_DENIED)
{
/* Under Windows 9X or on a samba share, ERROR_ACCESS_DENIED is
returned if you try to remove a file. On 9X the same error is
returned if you try to remove a non-empty directory. */
returned if you try to remove a file. On 9X the same error is
returned if you try to remove a non-empty directory. */
if (real_dir.file_attributes () != (DWORD) -1 &&
!(real_dir.file_attributes () & FILE_ATTRIBUTE_DIRECTORY))
set_errno (ENOTDIR);

View File

@ -23,6 +23,7 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
#include "cygerrno.h"
#include "fhandler.h"
#include "path.h"
@ -62,7 +63,7 @@ dtable::extend (int howmuch)
/* Try to allocate more space for fd table. We can't call realloc()
here to preserve old table if memory allocation fails */
if (!(newfds = (fhandler_base **) calloc (new_size, sizeof newfds[0])))
if (!(newfds = (fhandler_base **) ccalloc (HEAP_ARGV, new_size, sizeof newfds[0])))
{
debug_printf ("calloc failed");
return 0;
@ -70,7 +71,7 @@ dtable::extend (int howmuch)
if (fds)
{
memcpy (newfds, fds, size * sizeof (fds[0]));
free (fds);
cfree (fds);
}
size = new_size;
@ -151,7 +152,7 @@ dtable::release (int fd)
{
if (!not_open (fd))
{
delete (fds[fd]);
delete fds[fd]; /* CGF FIXME */
fds[fd] = NULL;
}
}
@ -240,7 +241,7 @@ fhandler_base *
dtable::build_fhandler (int fd, DWORD dev, const char *name, int unit)
{
fhandler_base *fh;
void *buf = calloc (1, sizeof (fhandler_union) + 100);
void *buf = ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_union) + 100);
dev &= FH_DEVMASK;
switch (dev)
@ -312,7 +313,7 @@ dtable::dup_worker (fhandler_base *oldfh)
newfh->set_io_handle (NULL);
if (oldfh->dup (newfh))
{
free (newfh);
cfree (newfh);
newfh = NULL;
return NULL;
}
@ -351,18 +352,21 @@ dtable::dup2 (int oldfd, int newfd)
}
SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
if ((size_t) newfd >= fdtab.size)
{
int inc_size = NOFILE_INCR * ((newfd + NOFILE_INCR - 1) / NOFILE_INCR) -
fdtab.size;
fdtab.extend (inc_size);
}
if ((size_t) newfd >= fdtab.size || newfd < 0)
{
syscall_printf ("new fd out of bounds: %d", newfd);
set_errno (EBADF);
goto done;
}
if ((size_t) newfd >= fdtab.size)
{
int inc_size = NOFILE_INCR * ((newfd + NOFILE_INCR - 1) / NOFILE_INCR) -
fdtab.size;
fdtab.extend (inc_size);
}
if (!not_open (newfd))
_close (newfd);
fds[newfd] = newfh;
@ -382,12 +386,12 @@ done:
select_record *
dtable::select_read (int fd, select_record *s)
{
if (fdtab.not_open (fd))
if (not_open (fd))
{
set_errno (EBADF);
return NULL;
}
fhandler_base *fh = fdtab[fd];
fhandler_base *fh = fds[fd];
s = fh->select_read (s);
s->fd = fd;
s->fh = fh;
@ -399,12 +403,12 @@ dtable::select_read (int fd, select_record *s)
select_record *
dtable::select_write (int fd, select_record *s)
{
if (fdtab.not_open (fd))
if (not_open (fd))
{
set_errno (EBADF);
return NULL;
}
fhandler_base *fh = fdtab[fd];
fhandler_base *fh = fds[fd];
s = fh->select_write (s);
s->fd = fd;
s->fh = fh;
@ -416,12 +420,12 @@ dtable::select_write (int fd, select_record *s)
select_record *
dtable::select_except (int fd, select_record *s)
{
if (fdtab.not_open (fd))
if (not_open (fd))
{
set_errno (EBADF);
return NULL;
}
fhandler_base *fh = fdtab[fd];
fhandler_base *fh = fds[fd];
s = fh->select_except (s);
s->fd = fd;
s->fh = fh;
@ -430,151 +434,33 @@ dtable::select_except (int fd, select_record *s)
return s;
}
/*
* Function to take an existant dtable array
* and linearize it into a memory buffer.
* If memory buffer is NULL, it returns the size
* of memory buffer needed to do the linearization.
* On error returns -1.
*/
int
dtable::linearize_fd_array (unsigned char *in_buf, int buflen)
/* Function to walk the fd table after an exec and perform
per-fhandler type fixups. */
void
dtable::fixup_after_exec (HANDLE parent, size_t sz, fhandler_base **f)
{
/* If buf == NULL, just precalculate length */
if (in_buf == NULL)
{
buflen = sizeof (size_t);
for (int i = 0, max_used_fd = -1; i < (int)size; i++)
if (!not_open (i) && !fds[i]->get_close_on_exec ())
{
buflen += i - (max_used_fd + 1);
buflen += fds[i]->cb + strlen (fds[i]->get_name ()) + 1
+ strlen (fds[i]->get_win32_name ()) + 1;
max_used_fd = i;
}
debug_printf ("needed buflen %d", buflen);
return buflen;
}
debug_printf ("in_buf = %x, buflen = %d", in_buf, buflen);
/*
* Now linearize each open fd (write a 0xff byte for a closed fd).
* Write the name of the open fd first (null terminated). This
* allows the de_linearizeing code to determine what kind of fhandler_xxx
* to create.
*/
size_t i;
int len, total_size;
total_size = sizeof (size_t);
if (total_size > buflen)
{
system_printf ("FATAL: linearize_fd_array exceeded buffer size");
return -1;
}
unsigned char *buf = in_buf;
buf += sizeof (size_t); /* skip over length which is added later */
for (i = 0, total_size = sizeof (size_t); total_size < buflen; i++)
{
if (not_open (i) || fds[i]->get_close_on_exec ())
{
debug_printf ("linearizing closed fd %d",i);
*buf = 0xff; /* place holder */
len = 1;
}
size = sz;
fds = f;
first_fd_for_open = 0;
for (size_t i = 0; i < size; i++)
if (fds[i])
if (fds[i]->get_close_on_exec ())
release (i);
else
{
len = fds[i]->linearize (buf);
debug_printf ("fd %d, len %d, name %s, device %p", i, len, buf,
fds[i]->get_device ());
fds[i]->clear_readahead ();
fds[i]->fixup_after_exec (parent);
}
total_size += len;
buf += len;
}
i--;
memcpy (in_buf, &i, sizeof (size_t));
if (total_size != buflen)
system_printf ("out of sync %d != %d", total_size, buflen);
return total_size;
}
/*
* Function to take a linearized dtable array in a memory buffer and
* re-create the original dtable array.
*/
LPBYTE
dtable::de_linearize_fd_array (LPBYTE buf)
{
int len, max_used_fd;
size_t inc_size;
debug_printf ("buf %x", buf);
/* First get the number of fd's - use this to set the fdtabsize.
NB. This is the only place in the code this should be done !!
*/
memcpy ((char *) &max_used_fd, buf, sizeof (int));
buf += sizeof (size_t);
inc_size = NOFILE_INCR * ((max_used_fd + NOFILE_INCR - 1) / NOFILE_INCR) -
size;
debug_printf ("max_used_fd %d, inc size %d", max_used_fd, inc_size);
if (inc_size > 0 && !extend (inc_size))
{
system_printf ("out of memory");
return NULL;
}
for (int i = 0; i <= max_used_fd; i++)
{
/* 0xFF means closed */
if (*buf == 0xff)
{
fds[i] = NULL;
buf++;
debug_printf ("closed fd %d", i);
continue;
}
/* fd was open - de_linearize it */
/* Get the null-terminated name. It is followed by an image of
the actual fhandler_* structure. Use the status field from
this to build a new fhandler type. */
DWORD status;
LPBYTE obuf = buf;
char *win32;
win32 = strchr ((char *)obuf, '\0') + 1;
buf = (LPBYTE)strchr ((char *)win32, '\0') + 1;
memcpy ((char *)&status, buf + FHSTATOFF, sizeof(DWORD));
debug_printf ("fd %d, name %s, win32 name %s, status %p",
i, obuf, win32, status);
len = build_fhandler (i, status, (const char *) NULL)->
de_linearize ((char *) buf, (char *) obuf, win32);
set_std_handle (i);
buf += len;
debug_printf ("len %d", buf - obuf);
}
first_fd_for_open = 0;
return buf;
}
void
dtable::fixup_after_fork (HANDLE parent)
{
SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
fhandler_base *fh;
for (size_t i = 0; i < size; i++)
if (!not_open (i))
if ((fh = fds[i]) != NULL)
{
fhandler_base *fh = fds[i];
if (fh->get_close_on_exec () || fh->get_need_fork_fixup ())
{
debug_printf ("fd %d(%s)", i, fh->get_name ());
@ -588,7 +474,7 @@ int
dtable::vfork_child_dup ()
{
fhandler_base **newtable;
newtable = (fhandler_base **) calloc (size, sizeof(fds[0]));
newtable = (fhandler_base **) ccalloc (HEAP_ARGV, size, sizeof(fds[0]));
int res = 1;
SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
@ -601,6 +487,7 @@ dtable::vfork_child_dup ()
set_errno (EBADF);
goto out;
}
fds_on_hold = fds;
fds = newtable;
out:
@ -617,7 +504,7 @@ dtable::vfork_parent_restore ()
fhandler_base **deleteme = fds;
fds = fds_on_hold;
fds_on_hold = NULL;
free (deleteme);
cfree (deleteme);
ReleaseResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
return;

View File

@ -30,8 +30,7 @@ public:
void release (int fd);
void init_std_file_from_handle (int fd, HANDLE handle, DWORD access, const char *name);
int dup2 (int oldfd, int newfd);
int linearize_fd_array (unsigned char *buf, int buflen);
LPBYTE de_linearize_fd_array (LPBYTE buf);
void fixup_after_exec (HANDLE, size_t, fhandler_base **);
fhandler_base *operator [](int fd) { return fds[fd]; }
select_record *select_read (int fd, select_record *s);
select_record *select_write (int fd, select_record *s);

View File

@ -27,6 +27,8 @@ extern DWORD chunksize;
BOOL reset_com = TRUE;
static BOOL envcache = TRUE;
static char **lastenviron = NULL;
/* List of names which are converted from dos to unix
* on the way in and back again on the way out.
*
@ -102,7 +104,7 @@ getwinenv (const char *env, const char *in_posix)
/* Convert windows path specs to POSIX, if appropriate.
*/
static void __stdcall
posify (int already_posix, char **here, const char *value)
posify (char **here, const char *value)
{
char *src = *here;
win_env *conv;
@ -111,22 +113,17 @@ posify (int already_posix, char **here, const char *value)
if (!(conv = getwinenv (src)))
return;
if (already_posix)
conv->add_cache (value, NULL);
else
{
/* Turn all the items from c:<foo>;<bar> into their
mounted equivalents - if there is one. */
/* Turn all the items from c:<foo>;<bar> into their
mounted equivalents - if there is one. */
char *outenv = (char *) malloc (1 + len + conv->posix_len (value));
memcpy (outenv, src, len);
conv->toposix (value, outenv + len);
conv->add_cache (outenv + len, value);
char *outenv = (char *) malloc (1 + len + conv->posix_len (value));
memcpy (outenv, src, len);
conv->toposix (value, outenv + len);
conv->add_cache (outenv + len, value);
debug_printf ("env var converted to %s", outenv);
*here = outenv;
free (src);
}
debug_printf ("env var converted to %s", outenv);
*here = outenv;
free (src);
}
/*
@ -175,6 +172,16 @@ getenv (const char *name)
return my_findenv (name, &offset);
}
extern int __stdcall
envsize (const char * const *in_envp, int debug_print)
{
const char * const *envp;
for (envp = in_envp; *envp; envp++)
if (debug_print)
debug_printf ("%s", *envp);
return (1 + envp - in_envp) * sizeof (const char *);
}
/* Takes similar arguments to setenv except that overwrite is
either -1, 0, or 1. 0 or 1 signify that the function should
perform similarly to setenv. Otherwise putenv is assumed. */
@ -202,17 +209,19 @@ _addenv (const char *name, const char *value, int overwrite)
}
else
{ /* Create new slot. */
char **env;
int sz = envsize (cur_environ ());
int allocsz = sz + sizeof (char *);
/* Search for the end of the environment. */
for (env = cur_environ (); *env; env++)
continue;
offset = env - cur_environ (); /* Number of elements currently in environ. */
offset = (sz - 1) / sizeof (char *);
/* Allocate space for additional element plus terminating NULL. */
__cygwin_environ = (char **) realloc (cur_environ (), (sizeof (char *) *
(offset + 2)));
if (__cygwin_environ == lastenviron)
lastenviron = __cygwin_environ = (char **) realloc (cur_environ (),
allocsz);
else if ((lastenviron = (char **) malloc (allocsz)) != NULL)
__cygwin_environ = (char **) memcpy ((char **) lastenviron,
__cygwin_environ, sz);
if (!__cygwin_environ)
return -1; /* Oops. No more memory. */
@ -261,7 +270,7 @@ putenv (const char *str)
if ((res = check_null_empty_path (str)))
{
if (res == ENOENT)
return 0;
return 0;
set_errno (res);
return -1;
}
@ -292,7 +301,7 @@ setenv (const char *name, const char *value, int overwrite)
if ((res = check_null_empty_path (name)))
{
if (res == ENOENT)
return 0;
return 0;
set_errno (res);
return -1;
}
@ -503,18 +512,15 @@ regopt (const char *name)
* environment variable and set appropriate options from it.
*/
void
environ_init (int already_posix)
environ_init (char **envp)
{
char *rawenv = GetEnvironmentStrings ();
int envsize, i;
char *rawenv;
int sz, i;
char *p;
char *newp, **envp;
char *newp;
int sawTERM = 0;
static char cygterm[] = "TERM=cygwin";
/* Allocate space for environment + trailing NULL + CYGWIN env. */
envp = (char **) malloc ((4 + (envsize = 100)) * sizeof (char *));
regopt ("default");
if (myself->progname[0])
regopt (myself->progname);
@ -525,6 +531,19 @@ environ_init (int already_posix)
allow_ntsec = TRUE;
#endif
if (envp)
{
sz = envsize (envp, 1);
char **newenv = (char **) malloc (sz);
envp = (char **) memcpy (newenv, envp, sz);
cfree (envp);
goto out;
}
/* Allocate space for environment + trailing NULL + CYGWIN env. */
lastenviron = envp = (char **) malloc ((4 + (sz = 100)) * sizeof (char *));
rawenv = GetEnvironmentStrings ();
/* Current directory information is recorded as variables of the
form "=X:=X:\foo\bar; these must be changed into something legal
(we could just ignore them but maybe an application will
@ -532,8 +551,8 @@ environ_init (int already_posix)
for (i = 0, p = rawenv; *p != '\0'; p = strchr (p, '\0') + 1, i++)
{
newp = strdup (p);
if (i >= envsize)
envp = (char **) realloc (envp, (4 + (envsize += 100)) *
if (i >= sz)
envp = (char **) realloc (envp, (4 + (sz += 100)) *
sizeof (char *));
envp[i] = newp;
if (*newp == '=')
@ -548,13 +567,16 @@ environ_init (int already_posix)
if (strncmp (newp, "CYGWIN=", sizeof("CYGWIN=") - 1) == 0)
parse_options (newp + sizeof("CYGWIN=") - 1);
if (*eq)
posify (already_posix, envp + i, *++eq ? eq : --eq);
posify (envp + i, *++eq ? eq : --eq);
debug_printf ("%s", envp[i]);
}
if (!sawTERM)
envp[i++] = cygterm;
envp[i] = NULL;
FreeEnvironmentStrings (rawenv);
out:
__cygwin_environ = envp;
update_envptrs ();
parse_options (NULL);

View File

@ -13,6 +13,7 @@ details. */
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include "cygheap.h"
#include <string.h>
#include "cygerrno.h"
#include "fhandler.h"
@ -26,12 +27,26 @@ struct __cygwin_perfile *perfile_table = NULL;
DWORD binmode = 0;
inline fhandler_base&
fhandler_base::operator =(fhandler_base &x)
{
memcpy (this, &x, sizeof *this);
unix_path_name_ = x.unix_path_name_ ? cstrdup (x.unix_path_name_) : NULL;
win32_path_name_ = x.win32_path_name_ ? cstrdup (x.win32_path_name_) : NULL;
rabuf = NULL;
ralen = 0;
raixget = 0;
raixput = 0;
rabuflen = 0;
return *this;
}
int
fhandler_base::puts_readahead (const char *s, size_t len = (size_t) -1)
{
int success = 1;
while ((*s || (len != (size_t) -1 && len--))
&& (success = put_readahead (*s++) > 0))
&& (success = put_readahead (*s++) > 0))
continue;
return success;
}
@ -137,16 +152,16 @@ fhandler_base::set_name (const char *unix_path, const char *win32_path, int unit
if (!no_free_names ())
{
if (unix_path_name_ != NULL && unix_path_name_ != fhandler_disk_dummy_name)
free (unix_path_name_);
cfree (unix_path_name_);
if (win32_path_name_ != NULL && unix_path_name_ != fhandler_disk_dummy_name)
free (win32_path_name_);
cfree (win32_path_name_);
}
unix_path_name_ = win32_path_name_ = NULL;
if (unix_path == NULL || !*unix_path)
return;
unix_path_name_ = strdup (unix_path);
unix_path_name_ = cstrdup (unix_path);
if (unix_path_name_ == NULL)
{
system_printf ("fatal error. strdup failed");
@ -154,11 +169,11 @@ fhandler_base::set_name (const char *unix_path, const char *win32_path, int unit
}
if (win32_path)
win32_path_name_ = strdup (win32_path);
win32_path_name_ = cstrdup (win32_path);
else
{
const char *fmt = get_native_name ();
win32_path_name_ = (char *) malloc (strlen(fmt) + 16);
win32_path_name_ = (char *) cmalloc (HEAP_STR, strlen(fmt) + 16);
__small_sprintf (win32_path_name_, fmt, unit);
}
@ -196,7 +211,7 @@ fhandler_base::raw_read (void *ptr, size_t ulen)
break;
default:
syscall_printf ("ReadFile %s failed, %E", unix_path_name_);
__seterrno_from_win_error (errcode);
__seterrno_from_win_error (errcode);
return -1;
break;
}
@ -205,37 +220,6 @@ fhandler_base::raw_read (void *ptr, size_t ulen)
return bytes_read;
}
int
fhandler_base::linearize (unsigned char *buf)
{
unsigned char *orig_buf = buf;
#define cbuf ((char *)buf)
strcpy (cbuf, get_name() ?: "");
char *p = strcpy (strchr (cbuf, '\0') + 1, get_win32_name ());
buf = (unsigned char *)memcpy (strchr (p, '\0') + 1, this, cb);
debug_printf ("access_ %p, status %p, io_handle %p, output_handle %p",
access_, status, get_io_handle (), get_output_handle ());
return (buf + cb) - orig_buf;
#undef cbuf
}
int
fhandler_base::de_linearize (const char *buf, const char *unix_name,
const char *win32_name)
{
int thiscb = cb;
memcpy(this, buf, cb);
unix_path_name_ = win32_path_name_ = NULL;
set_name (unix_name, win32_name);
debug_printf ("access_ %p, status %p, io_handle %p, output_handle %p",
access_, status, get_io_handle (), get_output_handle ());
if (thiscb != cb)
system_printf ("mismatch in linearize/delinearize %d != %d", thiscb, cb);
raixput = raixget = ralen = rabuflen = 0;
rabuf = NULL;
return cb;
}
/* Cover function to WriteFile to provide Posix interface and semantics
(as much as possible). */
int
@ -954,11 +938,11 @@ fhandler_disk_file::fstat (struct stat *buf)
directory. This is used, to set S_ISVTX, if needed. */
if (local.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
buf->st_mode |= S_IFDIR;
if (! get_file_attribute (has_acls (),
get_win32_name (),
&buf->st_mode,
&buf->st_uid,
&buf->st_gid))
if (!get_file_attribute (has_acls (),
get_win32_name (),
&buf->st_mode,
&buf->st_uid,
&buf->st_gid))
{
/* If read-only attribute is set, modify ntsec return value */
if (local.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
@ -979,7 +963,7 @@ fhandler_disk_file::fstat (struct stat *buf)
buf->st_mode = 0;
buf->st_mode |= STD_RBITS;
if (! (local.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
if (!(local.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
buf->st_mode |= STD_WBITS;
/* | S_IWGRP | S_IWOTH; we don't give write to group etc */
@ -1124,6 +1108,13 @@ fhandler_base::tcgetpgrp (void)
return -1;
}
void
fhandler_base::operator delete (void *p)
{
cfree (p);
return;
}
/* Normal I/O constructor */
fhandler_base::fhandler_base (DWORD devtype, const char *name, int unit):
access_ (0),
@ -1157,10 +1148,12 @@ fhandler_base::~fhandler_base (void)
if (!no_free_names ())
{
if (unix_path_name_ != NULL && unix_path_name_ != fhandler_disk_dummy_name)
free (unix_path_name_);
cfree (unix_path_name_);
if (win32_path_name_ != NULL && win32_path_name_ != fhandler_disk_dummy_name)
free (win32_path_name_);
cfree (win32_path_name_);
}
if (rabuf)
free (rabuf);
unix_path_name_ = win32_path_name_ = NULL;
}

View File

@ -149,13 +149,7 @@ public:
void set_name (const char * unix_path, const char * win32_path = NULL,
int unit = 0);
virtual fhandler_base& operator =(fhandler_base &x)
{
memcpy (this, &x, sizeof *this);
unix_path_name_ = x.unix_path_name_ ? strdup (x.unix_path_name_) : NULL;
win32_path_name_ = x.win32_path_name_ ? strdup (x.win32_path_name_) : NULL;
return *this;
};
virtual fhandler_base& operator =(fhandler_base &x);
fhandler_base (DWORD dev, const char *name = 0, int unit = 0);
virtual ~fhandler_base ();
@ -243,7 +237,8 @@ public:
unsigned long get_namehash () { return namehash_; }
virtual void hclose (HANDLE h) {CloseHandle (h);}
virtual void set_inheritance (HANDLE &h, int not_inheriting, const char *name = NULL);
virtual void set_inheritance (HANDLE &h, int not_inheriting,
const char *name = NULL);
/* fixup fd possibly non-inherited handles after fork */
void fork_fixup (HANDLE parent, HANDLE &h, const char *name);
@ -287,10 +282,7 @@ public:
virtual int raw_read (void *ptr, size_t ulen);
virtual int raw_write (const void *ptr, size_t ulen);
/* Function to save state of a fhandler_base into memory. */
virtual int linearize (unsigned char *);
/* Function to de-linearize into a fd */
virtual int de_linearize (const char *, const char *, const char *);
virtual void fixup_after_exec (HANDLE) {}
/* Virtual accessor functions to hide the fact
that some fd's have two handles. */
@ -307,6 +299,12 @@ public:
return windows_device_names[FHDEVN (status)];
}
virtual int bg_check (int) {return 1;}
void clear_readahead ()
{
raixput = raixget = ralen = rabuflen = 0;
rabuf = NULL;
}
void operator delete (void *);
};
class fhandler_socket: public fhandler_base
@ -377,9 +375,6 @@ protected:
public:
~fhandler_dev_raw (void);
/* Function to de-linearize into a fd */
int de_linearize (const char *, const char *, const char *);
int open (const char *path, int flags, mode_t mode = 0);
int close (void);
@ -497,7 +492,7 @@ public:
void dump ();
int is_tty () { return 1; }
void fixup_after_fork (HANDLE parent);
int de_linearize (const char *, const char *, const char *);
void fixup_after_exec (HANDLE);
/* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
don't use it for permissions checking. fhandler_tty_slave does
@ -604,7 +599,7 @@ public:
select_record *select_write (select_record *s);
select_record *select_except (select_record *s);
int ready_for_read (int fd, DWORD howlong, int ignra);
int de_linearize (const char *, const char *, const char *);
void fixup_after_exec (HANDLE);
void set_close_on_exec (int val);
void fixup_after_fork (HANDLE parent);
void set_input_state ()
@ -712,7 +707,7 @@ public:
int init (int);
int init_console ();
void fixup_after_fork (HANDLE parent);
int de_linearize (const char *, const char *, const char *);
void fixup_after_exec (HANDLE);
};
class fhandler_dev_null: public fhandler_base

View File

@ -8,10 +8,6 @@ This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
/* FIXMES:
Should the constructor call tcinit() explicitly rather than having
it sprinkled throughout here? */
#include "winsup.h"
#include <sys/termios.h>
#include <stdio.h>
@ -21,6 +17,7 @@ details. */
#include <unistd.h>
#include <wingdi.h>
#include <winuser.h>
#include <wincon.h>
#include <ctype.h>
#include "cygerrno.h"
#include "fhandler.h"
@ -1404,11 +1401,9 @@ set_console_title (char *title)
debug_printf ("title '%s'", buf);
}
int
fhandler_console::de_linearize (const char *buf, const char *unix_name,
const char *win32_name)
void
fhandler_console::fixup_after_exec (HANDLE)
{
int res = fhandler_base::de_linearize (buf, unix_name, win32_name);
HANDLE h = get_handle ();
HANDLE oh = get_output_handle ();
@ -1432,5 +1427,5 @@ fhandler_console::de_linearize (const char *buf, const char *unix_name,
CloseHandle (h);
CloseHandle (oh);
return res;
return;
}

View File

@ -20,7 +20,7 @@ details. */
#define URANDOM 9
#define PSEUDO_MULTIPLIER (6364136223846793005LL)
#define PSEUDO_SHIFTVAL (21)
#define PSEUDO_SHIFTVAL (21)
fhandler_dev_random::fhandler_dev_random (const char *name, int nunit)
: fhandler_base (FH_RANDOM, name),
@ -42,10 +42,10 @@ fhandler_dev_random::crypt_gen_random (void *ptr, size_t len)
{
if (!crypt_prov
&& !CryptAcquireContext (&crypt_prov, NULL, MS_DEF_PROV, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)
CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)
&& !CryptAcquireContext (&crypt_prov, NULL, MS_DEF_PROV, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET
| CRYPT_NEWKEYSET))
CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET
| CRYPT_NEWKEYSET))
{
debug_printf ("%E = CryptAquireContext()");
return FALSE;
@ -144,7 +144,7 @@ fhandler_dev_random::close (void)
{
if (crypt_prov)
while (!CryptReleaseContext (crypt_prov, 0)
&& GetLastError () == ERROR_BUSY)
&& GetLastError () == ERROR_BUSY)
Sleep(10);
return 0;
}

View File

@ -16,6 +16,7 @@
#include <cygwin/rdevio.h>
#include <sys/mtio.h>
#include "cygheap.h"
#include "cygerrno.h"
#include "fhandler.h"
#include "path.h"
@ -25,7 +26,7 @@
also related to the used tape device. */
static BOOL write_file (HANDLE fh, const void *buf, DWORD to_write,
DWORD *written, int *err)
DWORD *written, int *err)
{
BOOL ret;
@ -33,20 +34,20 @@ static BOOL write_file (HANDLE fh, const void *buf, DWORD to_write,
if (!(ret = WriteFile (fh, buf, to_write, written, 0)))
{
if ((*err = GetLastError ()) == ERROR_MEDIA_CHANGED
|| *err == ERROR_BUS_RESET)
{
*err = 0;
if (!(ret = WriteFile (fh, buf, to_write, written, 0)))
*err = GetLastError ();
}
|| *err == ERROR_BUS_RESET)
{
*err = 0;
if (!(ret = WriteFile (fh, buf, to_write, written, 0)))
*err = GetLastError ();
}
}
syscall_printf ("%d (err %d) = WriteFile (%d, %d, write %d, written %d, 0)",
ret, *err, fh, buf, to_write, *written);
ret, *err, fh, buf, to_write, *written);
return ret;
}
static BOOL read_file (HANDLE fh, void *buf, DWORD to_read,
DWORD *read, int *err)
DWORD *read, int *err)
{
BOOL ret;
@ -54,15 +55,15 @@ static BOOL read_file (HANDLE fh, void *buf, DWORD to_read,
if (!(ret = ReadFile(fh, buf, to_read, read, 0)))
{
if ((*err = GetLastError ()) == ERROR_MEDIA_CHANGED
|| *err == ERROR_BUS_RESET)
{
*err = 0;
if (!(ret = ReadFile (fh, buf, to_read, read, 0)))
*err = GetLastError ();
}
|| *err == ERROR_BUS_RESET)
{
*err = 0;
if (!(ret = ReadFile (fh, buf, to_read, read, 0)))
*err = GetLastError ();
}
}
syscall_printf ("%d (err %d) = ReadFile (%d, %d, to_read %d, read %d, 0)",
ret, *err, fh, buf, to_read, *read);
ret, *err, fh, buf, to_read, *read);
return ret;
}
@ -96,13 +97,13 @@ fhandler_dev_raw::writebuf (void)
memset (devbuf + devbufend, 0, devbufsiz - devbufend);
if (get_device () != FH_TAPE)
to_write = ((devbufend - 1) / 512 + 1) * 512;
to_write = ((devbufend - 1) / 512 + 1) * 512;
else if (varblkop)
to_write = devbufend;
to_write = devbufend;
else
to_write = devbufsiz;
to_write = devbufsiz;
if (!write_file (get_handle (), devbuf, to_write, &written, &ret)
&& is_eom (ret))
&& is_eom (ret))
eom_detected = 1;
if (written)
has_written = 1;
@ -120,23 +121,11 @@ fhandler_dev_raw::fhandler_dev_raw (DWORD devtype, const char *name, int unit) :
fhandler_dev_raw::~fhandler_dev_raw (void)
{
delete[]devbuf;
if (devbufsiz >= 1L)
cfree (devbuf);
clear ();
}
int
fhandler_dev_raw::de_linearize (const char *buf, const char *unix_name,
const char *win32_name)
{
int ret = fhandler_base::de_linearize (buf, unix_name, win32_name);
if (devbufsiz > 1L)
{
devbuf = new char[devbufsiz];
devbufstart = devbufend = 0;
}
return ret;
}
int
fhandler_dev_raw::open (const char *path, int flags, mode_t)
{
@ -150,7 +139,7 @@ fhandler_dev_raw::open (const char *path, int flags, mode_t)
if (ret)
{
if (devbufsiz > 1L)
devbuf = new char[devbufsiz];
devbuf = (char *) cmalloc (HEAP_BUF, devbufsiz);
}
else
devbufsiz = 0;
@ -174,9 +163,9 @@ fhandler_dev_raw::fstat (struct stat *buf)
memset (buf, 0, sizeof *buf);
buf->st_mode = S_IFCHR |
S_IRUSR | S_IWUSR |
S_IRGRP | S_IWGRP |
S_IROTH | S_IWOTH;
S_IRUSR | S_IWUSR |
S_IRGRP | S_IWGRP |
S_IROTH | S_IWOTH;
buf->st_nlink = 1;
buf->st_blksize = devbuf ? devbufsiz : 1;
buf->st_dev = buf->st_rdev = get_device () << 8 | (unit & 0xff);
@ -241,9 +230,9 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen)
{
if (!varblkop && len >= devbufsiz)
{
if (get_device () == FH_TAPE)
if (get_device () == FH_TAPE)
bytes_to_read = (len / devbufsiz) * devbufsiz;
else
else
bytes_to_read = (len / 512) * 512;
tgt = (char *) ptr;
debug_printf ("read %d bytes direct from file",bytes_to_read);
@ -252,9 +241,9 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen)
{
bytes_to_read = devbufsiz;
tgt = devbuf;
if (varblkop)
if (varblkop)
debug_printf ("read variable bytes from file into buffer");
else
else
debug_printf ("read %d bytes from file into buffer",
bytes_to_read);
}
@ -262,7 +251,7 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen)
{
if (!is_eof (ret) && !is_eom (ret))
{
debug_printf ("return -1, set errno to EACCES");
debug_printf ("return -1, set errno to EACCES");
set_errno (EACCES);
return -1;
}
@ -276,7 +265,7 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen)
{
if (!bytes_read && is_eom (ret))
{
debug_printf ("return -1, set errno to ENOSPC");
debug_printf ("return -1, set errno to ENOSPC");
set_errno (ENOSPC);
return -1;
}
@ -304,7 +293,7 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen)
{
if (!is_eof (ret) && !is_eom (ret))
{
debug_printf ("return -1, set errno to EACCES");
debug_printf ("return -1, set errno to EACCES");
set_errno (EACCES);
return -1;
}
@ -317,7 +306,7 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen)
}
else if (is_eom (ret))
{
debug_printf ("return -1, set errno to ENOSPC");
debug_printf ("return -1, set errno to ENOSPC");
set_errno (ENOSPC);
return -1;
}
@ -352,7 +341,7 @@ fhandler_dev_raw::raw_write (const void *ptr, size_t len)
while (len > 0)
{
if (!varblkop &&
(len < devbufsiz || devbufend > 0) && devbufend < devbufsiz)
(len < devbufsiz || devbufend > 0) && devbufend < devbufsiz)
{
bytes_to_write = min (len, devbufsiz - devbufend);
memcpy (devbuf + devbufend, p, bytes_to_write);
@ -456,7 +445,7 @@ fhandler_dev_raw::dup (fhandler_base *child)
fhc->devbufsiz = devbufsiz;
if (devbufsiz > 1L)
{
fhc->devbuf = new char[devbufsiz];
fhc->devbuf = (char *) cmalloc (HEAP_BUF, devbufsiz);
memcpy (fhc->devbuf, devbuf, devbufend);
}
fhc->devbufstart = devbufstart;
@ -499,12 +488,12 @@ fhandler_dev_raw::ioctl (unsigned int cmd, void *buf)
ret = ERROR_INVALID_PARAMETER;
else if (!devbuf || op->rd_parm != devbufsiz)
{
char *buf = new char[op->rd_parm];
char *buf = (char *) cmalloc (HEAP_BUF, op->rd_parm);
if (devbuf)
{
memcpy (buf, devbuf + devbufstart, devbufend - devbufstart);
devbufend -= devbufstart;
delete[]devbuf;
cfree (devbuf);
}
else
devbufend = 0;

View File

@ -503,7 +503,7 @@ fhandler_serial::tcsetattr (int action, const struct termios *t)
state.Parity = NOPARITY;
state.fBinary = TRUE; /* Binary transfer */
state.EofChar = 0; /* No end-of-data in binary mode */
state.EofChar = 0; /* No end-of-data in binary mode */
state.fNull = FALSE; /* Don't discard nulls in binary mode */
/* -------------- Parity errors ------------------ */
@ -867,14 +867,12 @@ fhandler_serial::fixup_after_fork (HANDLE parent)
debug_printf ("io_status.hEvent %p", io_status.hEvent);
}
int
fhandler_serial::de_linearize (const char *buf, const char *unix_name,
const char *win32_name)
void
fhandler_serial::fixup_after_exec (HANDLE)
{
int res = fhandler_base::de_linearize (buf, unix_name, win32_name);
overlapped_setup ();
debug_printf ("io_status.hEvent %p", io_status.hEvent);
return res;
return;
}
int

View File

@ -80,12 +80,12 @@ fhandler_dev_tape::open (const char *path, int flags, mode_t)
struct mtpos pos;
if (! ioctl (MTIOCGET, &get))
/* Tape drive supports and is set to variable block size. */
if (get.mt_dsreg == 0)
devbufsiz = get.mt_maxblksize;
else
/* Tape drive supports and is set to variable block size. */
if (get.mt_dsreg == 0)
devbufsiz = get.mt_maxblksize;
else
devbufsiz = get.mt_dsreg;
varblkop = get.mt_dsreg == 0;
varblkop = get.mt_dsreg == 0;
if (devbufsiz > 1L)
devbuf = new char [ devbufsiz ];
@ -324,36 +324,36 @@ fhandler_dev_tape::ioctl (unsigned int cmd, void *buf)
break;
}
if ((op->mt_count == 0
&& !tape_get_feature (TAPE_DRIVE_VARIABLE_BLOCK))
|| (op->mt_count > 0
&& (op->mt_count < min || op->mt_count > max)))
&& !tape_get_feature (TAPE_DRIVE_VARIABLE_BLOCK))
|| (op->mt_count > 0
&& (op->mt_count < min || op->mt_count > max)))
{
ret = ERROR_INVALID_PARAMETER;
break;
}
if (devbuf && op->mt_count > 0
&& (size_t) op->mt_count < devbufend - devbufstart)
&& (size_t) op->mt_count < devbufend - devbufstart)
{
ret = ERROR_MORE_DATA;
break;
}
if (! (ret = tape_set_blocksize (op->mt_count)))
{
size_t size = 0;
if (op->mt_count == 0)
{
struct mtget get;
if ((ret = tape_status (&get)) != NO_ERROR)
break;
size = get.mt_maxblksize;
ret = NO_ERROR;
}
size_t size = 0;
if (op->mt_count == 0)
{
struct mtget get;
if ((ret = tape_status (&get)) != NO_ERROR)
break;
size = get.mt_maxblksize;
ret = NO_ERROR;
}
char *buf = new char [ size ];
if (!buf)
{
ret = ERROR_OUTOFMEMORY;
break;
}
if (!buf)
{
ret = ERROR_OUTOFMEMORY;
break;
}
if (devbuf)
{
memcpy(buf,devbuf + devbufstart, devbufend - devbufstart);
@ -365,7 +365,7 @@ fhandler_dev_tape::ioctl (unsigned int cmd, void *buf)
devbufstart = 0;
devbuf = buf;
devbufsiz = size;
varblkop = op->mt_count == 0;
varblkop = op->mt_count == 0;
}
}
break;

View File

@ -22,6 +22,7 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
/* Tty master stuff */
@ -433,7 +434,7 @@ fhandler_tty_slave::fhandler_tty_slave(int num, const char *name) :
ttynum = num;
/* FIXME: This is wasteful. We should rewrite the set_name path to eliminate the
need for double allocates. */
unix_path_name_ = (char *) realloc (unix_path_name_, strlen(win32_path_name_) + 1);
unix_path_name_ = (char *) crealloc (unix_path_name_, strlen(win32_path_name_) + 1);
strcpy (unix_path_name_, win32_path_name_);
unix_path_name_[0] = unix_path_name_[4] = '/';
debug_printf ("unix '%s', win32 '%s'", unix_path_name_, win32_path_name_);
@ -1075,14 +1076,12 @@ fhandler_tty_master::fixup_after_fork (HANDLE child)
console->fixup_after_fork (child);
}
int
fhandler_tty_master::de_linearize (const char *buf, const char *unix_name,
const char *win32_name)
void
fhandler_tty_master::fixup_after_exec (HANDLE)
{
int res = fhandler_base::de_linearize (buf, unix_name, win32_name);
console->close ();
init_console ();
return res;
return;
}
int

View File

@ -22,6 +22,7 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
#include "child_info.h"
#include "perthread.h"
@ -37,14 +38,14 @@ DWORD NO_COPY chunksize = 0;
void
per_thread::set (void *s)
{
if (s == PER_THREAD_FORK_CLEAR)
{
tls = TlsAlloc ();
s = NULL;
}
TlsSetValue (get_tls (), s);
}
{
if (s == PER_THREAD_FORK_CLEAR)
{
tls = TlsAlloc ();
s = NULL;
}
TlsSetValue (get_tls (), s);
}
static void
stack_base (child_info_fork &ch)
@ -356,7 +357,7 @@ fork ()
hParent = NULL;
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hParent, 0, 1,
DUPLICATE_SAME_ACCESS))
DUPLICATE_SAME_ACCESS))
{
system_printf ("couldn't create handle to myself for child, %E");
goto cleanup;
@ -365,13 +366,13 @@ fork ()
/* Remove impersonation */
uid_t uid = geteuid();
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (myself->orig_uid);
seteuid (myself->orig_uid);
char sa_buf[1024];
rc = CreateProcessA (myself->progname, /* image to run */
myself->progname, /* what we send in arg0 */
allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
TRUE, /* inherit handles from parent */
c_flags,
NULL, /* environment filled in later */
@ -388,9 +389,9 @@ fork ()
ForceCloseHandle(subproc_ready);
ForceCloseHandle(forker_finished);
subproc_ready = forker_finished = NULL;
/* Restore impersonation */
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (uid);
/* Restore impersonation */
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (uid);
return -1;
}
@ -402,7 +403,7 @@ fork ()
/* Restore impersonation */
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (uid);
seteuid (uid);
ProtectHandle (pi.hThread);
/* Protect the handle but name it similarly to the way it will
@ -413,7 +414,7 @@ fork ()
if (last_fork_proc)
CloseHandle (last_fork_proc);
if (!DuplicateHandle (hMainProc, pi.hProcess, hMainProc, &last_fork_proc,
0, FALSE, DUPLICATE_SAME_ACCESS))
0, FALSE, DUPLICATE_SAME_ACCESS))
system_printf ("couldn't create last_fork_proc, %E");
}
@ -528,15 +529,15 @@ fork ()
debug_printf ("pid %d, ppid %d", x, myself->ppid);
/* Restore the inheritance state as in parent
Don't call setuid here! The flags are already set. */
Don't call setuid here! The flags are already set. */
if (myself->impersonated)
{
debug_printf ("Impersonation of child, token: %d", myself->token);
if (myself->token == INVALID_HANDLE_VALUE)
RevertToSelf (); // probably not needed
else if (!ImpersonateLoggedOnUser (myself->token))
system_printf ("Impersonate for forked child failed: %E");
}
{
debug_printf ("Impersonation of child, token: %d", myself->token);
if (myself->token == INVALID_HANDLE_VALUE)
RevertToSelf (); // probably not needed
else if (!ImpersonateLoggedOnUser (myself->token))
system_printf ("Impersonate for forked child failed: %E");
}
sync_with_parent ("after longjmp.", TRUE);
ProtectHandle (hParent);
@ -567,6 +568,7 @@ fork ()
MALLOC_CHECK;
cygheap_fixup_in_child (hParent);
fdtab.fixup_after_fork (hParent);
signal_fixup_after_fork ();
exec_fixup_after_fork ();

View File

@ -14,12 +14,8 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "heap.h"
#define brksize ((char *) user_data->heaptop - (char *) user_data->heapbase)
#define brk (user_data->heapptr)
#define brkbase (user_data->heapbase)
#define brktop (user_data->heaptop)
#define brkchunk (cygwin_shared->heap_chunk_size ())
#define assert(x)
static unsigned page_const = 0;

22
winsup/cygwin/heap.h Normal file
View File

@ -0,0 +1,22 @@
/* heap.h: Cygwin heap manager definitions.
Copyright 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. */
/* Heap management. */
void heap_init (void);
void malloc_init (void);
#define inheap(s) (brk && ((char *) (s) >= (char *) brkbase) && ((char *) (s) <= (char *) brktop))
#define brksize ((char *) user_data->heaptop - (char *) user_data->heapbase)
#define brk (user_data->heapptr)
#define brkbase (user_data->heapbase)
#define brktop (user_data->heaptop)
#define brkchunk (cygwin_shared->heap_chunk_size ())

View File

@ -29,7 +29,7 @@ WINAPI dll_entry (HANDLE h, DWORD reason, void *static_load)
if (user_data->threadinterface)
{
if ( !TlsSetValue(user_data->threadinterface->reent_index,
&user_data->threadinterface->reents))
&user_data->threadinterface->reents))
api_fatal("Sig proc MT init failed\n");
}
break;

View File

@ -13,6 +13,9 @@ details. */
#include "winsup.h"
#include <stdlib.h>
#include <assert.h>
#include "cygheap.h"
#include "heap.h"
#include "sync.h"
/* we provide these stubs to call into a user's
@ -60,6 +63,8 @@ extern "C" void
_free_r (struct _reent *, void *p)
{
export_malloc_called = 1;
assert (!incygheap (p));
assert (inheap (p));
free (p);
}
#undef free
@ -68,6 +73,8 @@ extern "C" void *
_realloc_r (struct _reent *, void *p, size_t size)
{
export_malloc_called = 1;
assert (!incygheap (p));
assert (inheap (p));
return realloc (p, size);
}
#undef realloc
@ -122,6 +129,22 @@ calloc (size_t nmemb, size_t size)
res = user_data->calloc (nmemb, size);
return res;
}
extern "C" char *
strdup (const char *s)
{
char *p;
size_t len = strlen (s) + 1;
if ((p = (char *) malloc (len)) != NULL)
memcpy (p, s, len);
return p;
}
extern "C" char *
_strdup_r (struct _reent *, const char *s)
{
return strdup (s);
}
#endif
/* These routines are used by the application if it
@ -178,22 +201,6 @@ export_calloc (size_t nmemb, size_t size)
return res;
}
extern "C" char *
strdup (const char *s)
{
char *p;
size_t len = strlen (s) + 1;
if ((p = (char *) malloc (len)) != NULL)
memcpy (p, s, len);
return p;
}
extern "C" char *
_strdup_r (struct _reent *, const char *s)
{
return strdup (s);
}
/* We use a critical section to lock access to the malloc data
structures. This permits malloc to be called from different
threads. Note that it does not make malloc reentrant, and it does

View File

@ -210,7 +210,7 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
{
set_errno (EBADF);
syscall_printf ("-1 = mmap(): EBADF");
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) -1;
}
hFile = fdtab[fd]->get_handle ();
@ -235,7 +235,7 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
__seterrno ();
syscall_printf ("-1 = mmap(): MapViewOfFileEx failed with %E");
CloseHandle (h);
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) -1;
}
}
@ -247,7 +247,7 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
__seterrno ();
syscall_printf ("-1 = mmap(): MapViewOfFile failed with %E");
CloseHandle (h);
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) -1;
}
}
@ -273,7 +273,7 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
CloseHandle (h);
set_errno (ENOMEM);
syscall_printf ("-1 = mmap(): ENOMEM");
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) -1;
}
l = mmapped_areas->add_list (l, fd);
@ -327,7 +327,7 @@ munmap (caddr_t addr, size_t len)
/* Delete the entry. */
l->erase (li);
syscall_printf ("0 = munmap(): %x", addr);
ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap");
ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap");
return 0;
}
}

View File

@ -354,18 +354,18 @@ cygwin_socket (int af, int type, int protocol)
soc = socket (AF_INET, type, 0);
if (soc == INVALID_SOCKET)
{
set_winsock_errno ();
goto done;
}
{
set_winsock_errno ();
goto done;
}
soc = duplicate_socket (soc);
const char *name;
if (af == AF_INET)
name = (type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp");
name = (type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp");
else
name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket");
name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket");
fdsock (fd, name, soc);
res = fd;
@ -781,11 +781,11 @@ cygwin_bind (int fd, struct sockaddr *my_addr, int addrlen)
int len = sizeof sin;
int fd;
if (strlen (un_addr->sun_path) >= UNIX_PATH_LEN)
{
set_errno (ENAMETOOLONG);
goto out;
}
if (strlen (un_addr->sun_path) >= UNIX_PATH_LEN)
{
set_errno (ENAMETOOLONG);
goto out;
}
sin.sin_family = AF_INET;
sin.sin_port = 0;
sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
@ -805,36 +805,36 @@ cygwin_bind (int fd, struct sockaddr *my_addr, int addrlen)
sin.sin_port = ntohs (sin.sin_port);
debug_printf ("AF_UNIX: socket bound to port %u", sin.sin_port);
/* bind must fail if file system socket object already exists
so _open() is called with O_EXCL flag. */
/* bind must fail if file system socket object already exists
so _open() is called with O_EXCL flag. */
fd = _open (un_addr->sun_path,
O_WRONLY | O_CREAT | O_EXCL | O_BINARY,
0);
O_WRONLY | O_CREAT | O_EXCL | O_BINARY,
0);
if (fd < 0)
{
if (get_errno () == EEXIST)
set_errno (EADDRINUSE);
{
if (get_errno () == EEXIST)
set_errno (EADDRINUSE);
goto out;
}
}
char buf[sizeof (SOCKET_COOKIE) + 10];
__small_sprintf (buf, "%s%u", SOCKET_COOKIE, sin.sin_port);
len = strlen (buf) + 1;
char buf[sizeof (SOCKET_COOKIE) + 10];
__small_sprintf (buf, "%s%u", SOCKET_COOKIE, sin.sin_port);
len = strlen (buf) + 1;
/* Note that the terminating nul is written. */
if (_write (fd, buf, len) != len)
{
/* Note that the terminating nul is written. */
if (_write (fd, buf, len) != len)
{
save_errno here;
_close (fd);
_unlink (un_addr->sun_path);
}
else
{
_close (fd);
chmod (un_addr->sun_path,
(S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO) & ~myself->umask);
_close (fd);
_unlink (un_addr->sun_path);
}
else
{
_close (fd);
chmod (un_addr->sun_path,
(S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO) & ~myself->umask);
res = 0;
}
}
#undef un_addr
}
else if (bind (sock->get_socket (), my_addr, addrlen))
@ -1032,7 +1032,7 @@ getdomainname (char *domain, int len)
* \Device\<Netcard>, where netcard is the name of the net device.
* Then look under:
* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<NetCard>\
* Parameters\Tcpip
* Parameters\Tcpip
* at the IPAddress, Subnetmask and DefaultGateway values for the
* required values.
*
@ -1709,36 +1709,36 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
case SIOCGIFNETMASK:
case SIOCGIFADDR:
{
char buf[2048];
struct ifconf ifc;
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
struct ifreq *ifrp;
char buf[2048];
struct ifconf ifc;
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
struct ifreq *ifrp;
struct ifreq *ifr = (struct ifreq *) p;
if (ifr == 0)
{
debug_printf("ifr == NULL\n");
set_errno (EINVAL);
return -1;
}
struct ifreq *ifr = (struct ifreq *) p;
if (ifr == 0)
{
debug_printf("ifr == NULL\n");
set_errno (EINVAL);
return -1;
}
res = get_ifconf (&ifc, cmd);
if (res)
if (res)
{
debug_printf ("error in get_ifconf\n");
break;
}
debug_printf(" name: %s\n", ifr->ifr_name);
for (ifrp = ifc.ifc_req;
(caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len;
++ifrp)
{
debug_printf("testname: %s\n", ifrp->ifr_name);
if (! strcmp (ifrp->ifr_name, ifr->ifr_name))
{
switch (cmd)
debug_printf(" name: %s\n", ifr->ifr_name);
for (ifrp = ifc.ifc_req;
(caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len;
++ifrp)
{
debug_printf("testname: %s\n", ifrp->ifr_name);
if (! strcmp (ifrp->ifr_name, ifr->ifr_name))
{
switch (cmd)
{
case SIOCGIFADDR:
ifr->ifr_addr = ifrp->ifr_addr;
@ -1750,15 +1750,15 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
ifr->ifr_netmask = ifrp->ifr_netmask;
break;
}
break;
}
}
if ((caddr_t) ifrp >= ifc.ifc_buf + ifc.ifc_len)
{
set_errno (EINVAL);
return -1;
}
break;
break;
}
}
if ((caddr_t) ifrp >= ifc.ifc_buf + ifc.ifc_len)
{
set_errno (EINVAL);
return -1;
}
break;
}
case FIOASYNC:
res = WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO,

View File

@ -134,22 +134,22 @@ read_etc_passwd ()
}
fclose (f);
passwd_state = loaded;
passwd_state = loaded;
}
else
{
debug_printf ("Emulating /etc/passwd");
char user_name [ MAX_USER_NAME ];
DWORD user_name_len = MAX_USER_NAME;
if (! GetUserNameA (user_name, &user_name_len))
{
strncpy (user_name, "Administrator", MAX_USER_NAME);
debug_printf ("Failed to get current user name. %E");
}
snprintf (linebuf, sizeof (linebuf), "%s::%u:%u::%s:/bin/sh", user_name,
debug_printf ("Emulating /etc/passwd");
char user_name [ MAX_USER_NAME ];
DWORD user_name_len = MAX_USER_NAME;
if (! GetUserNameA (user_name, &user_name_len))
{
strncpy (user_name, "Administrator", MAX_USER_NAME);
debug_printf ("Failed to get current user name. %E");
}
snprintf (linebuf, sizeof (linebuf), "%s::%u:%u::%s:/bin/sh", user_name,
DEFAULT_UID, DEFAULT_GID, getenv ("HOME") ?: "/");
add_pwd_line (linebuf);
passwd_state = emulated;
add_pwd_line (linebuf);
passwd_state = emulated;
}
}
@ -164,7 +164,7 @@ search_for (uid_t uid, const char *name)
{
res = passwd_buf + i;
if (res->pw_uid == DEFAULT_UID)
default_pw = res;
default_pw = res;
/* on Windows NT user names are case-insensitive */
if (name)
{

View File

@ -88,6 +88,7 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
static int normalize_win32_path (const char *cwd, const char *src, char *dst);
static char *getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot);
@ -150,15 +151,71 @@ struct symlink_info
/* Cache getcwd value. FIXME: We need a lock for these in order to
support multiple threads. */
#ifdef _MT_SAFE
#define cwd_win32 _reent_winsup()->_cwd_win32
#define cwd_posix _reent_winsup()->_cwd_posix
#define cwd_hash _reent_winsup()->_cwd_hash
#else
static char *cwd_win32;
static char *cwd_posix;
static unsigned long cwd_hash;
#endif
#define TMPCWD ((char *) alloca (MAX_PATH + 1))
struct cwdstuff
{
char *posix;
char *win32;
DWORD hash;
muto *lock;
};
cwdstuff cwd;
char * __stdcall
cwd_win32 (char *buf)
{
char *ret;
cwd.lock->acquire ();
if (cwd.win32 == NULL)
ret = NULL;
else if (buf == NULL)
ret = cwd.win32;
else
ret = strcpy (buf, cwd.win32);
cwd.lock->release ();
return ret;
}
char * __stdcall
cwd_posix (char *buf)
{
char *ret;
cwd.lock->acquire ();
if (cwd.posix == NULL)
ret = NULL;
else if (buf == NULL)
ret = cwd.posix;
else
ret = strcpy (buf, cwd.posix);
cwd.lock->release ();
return ret;
}
DWORD __stdcall
cwd_hash ()
{
DWORD hashnow;
cwd.lock->acquire ();
hashnow = cwd.hash;
cwd.lock->release ();
return hashnow;
}
void __stdcall
cwd_init ()
{
cwd.lock = new_muto (FALSE, "cwd");
}
void __stdcall
cwd_fixup_after_exec (char *win32, char *posix, DWORD hash)
{
cwd.win32 = win32;
cwd.posix = posix;
cwd.hash = hash;
}
#define ischrootpath(path) \
(myself->rootlen && \
@ -965,7 +1022,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *win32_path,
if (strpbrk (src_path, ":\\") != NULL)
{
debug_printf ("%s already win32", src_path);
rc = normalize_win32_path (cwd_win32, src_path, dst);
rc = normalize_win32_path (cwd_win32 (TMPCWD), src_path, dst);
if (rc)
{
debug_printf ("normalize_win32_path failed, rc %d", rc);
@ -1082,10 +1139,12 @@ fillin:
/* Compute relative path if asked to and able to. */
unsigned cwdlen;
cwdlen = 0; /* avoid a (hopefully) bogus compiler warning */
char *cwd_win32_now;
cwd_win32_now = cwd_win32 (TMPCWD);
if (win32_path == NULL)
/* nothing to do */;
else if (isrelpath &&
path_prefix_p (cwd_win32, dst, cwdlen = strlen (cwd_win32)))
path_prefix_p (cwd_win32_now, dst, cwdlen = strlen (cwd_win32_now)))
{
size_t n = strlen (dst);
if (n < cwdlen)
@ -1095,7 +1154,7 @@ fillin:
if (n == cwdlen)
dst += cwdlen;
else
dst += isdirsep (cwd_win32[cwdlen - 1]) ? cwdlen : cwdlen + 1;
dst += isdirsep (cwd_win32_now[cwdlen - 1]) ? cwdlen : cwdlen + 1;
memmove (win32_path, dst, strlen (dst) + 1);
if (!*win32_path)
@ -2453,10 +2512,9 @@ hash_path_name (unsigned long hash, const char *name)
Otherwise the inodes same will differ depending on whether a file is
referenced with an absolute value or relatively. */
if (*name != '\\' && (cwd_win32 == NULL ||
get_cwd_win32 ()))
if (*name != '\\' && (cwd_win32 (TMPCWD) == NULL || get_cwd_win32 ()))
{
hash = cwd_hash;
hash = cwd_hash ();
if (name[0] == '.' && name[1] == '\0')
return hash;
hash = hash_path_name (hash, "\\");
@ -2481,18 +2539,20 @@ get_cwd_win32 ()
{
DWORD dlen, len;
cwd.lock->acquire ();
for (dlen = 256; ; dlen *= 2)
{
cwd_win32 = (char *) realloc (cwd_win32, dlen + 2);
if ((len = GetCurrentDirectoryA (dlen, cwd_win32)) < dlen)
cwd.win32 = (char *) crealloc (cwd.win32, dlen + 2);
if ((len = GetCurrentDirectoryA (dlen, cwd.win32)) < dlen)
break;
}
if (len == 0)
__seterrno ();
else
cwd_hash = hash_path_name (0, cwd_win32);
cwd.hash = hash_path_name (0, cwd.win32);
cwd.lock->release ();
return len;
}
@ -2504,16 +2564,18 @@ getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot)
char *resbuf = NULL;
size_t len = ulen;
if (cwd_win32 == NULL && !get_cwd_win32 ())
if (cwd_win32 (TMPCWD) == NULL && !get_cwd_win32 ())
return NULL;
char *cwd_win32_now = cwd_win32 (TMPCWD);
char *cwd_posix_now = cwd_posix (TMPCWD);
if (!posix_p)
{
if (strlen (cwd_win32) >= len)
if (strlen (cwd_win32_now) >= len)
set_errno (ERANGE);
else
{
strcpy (buf, cwd_win32);
strcpy (buf, cwd_win32_now);
resbuf = buf;
}
@ -2521,21 +2583,21 @@ getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot)
resbuf, resbuf ? resbuf : "", buf, len);
return resbuf;
}
else if (cwd_posix != NULL)
else if (cwd_posix_now != NULL)
{
debug_printf("myself->root: %s, cwd_posix: %s", myself->root, cwd_posix);
if (strlen (cwd_posix) >= len)
debug_printf("myself->root: %s, cwd_posix: %s", myself->root, cwd_posix_now);
if (strlen (cwd_posix_now) >= len)
set_errno (ERANGE);
else if (with_chroot && ischrootpath(cwd_posix))
else if (with_chroot && ischrootpath(cwd_posix_now))
{
strcpy (buf, cwd_posix + myself->rootlen);
strcpy (buf, cwd_posix_now + myself->rootlen);
if (!buf[0])
strcpy (buf, "/");
resbuf = buf;
}
else
{
strcpy (buf, cwd_posix);
strcpy (buf, cwd_posix_now);
resbuf = buf;
}
@ -2549,30 +2611,29 @@ getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot)
char temp[MAX_PATH];
/* Turn from Win32 style to our style. */
cygwin_shared->mount.conv_to_posix_path (cwd_win32, temp, 0);
cygwin_shared->mount.conv_to_posix_path (cwd_win32_now, temp, 0);
size_t tlen = strlen (temp);
if (with_chroot && ischrootpath (temp))
tlen -= myself->rootlen;
cwd_posix = (char *) realloc (
cwd_posix, tlen + 1);
if (cwd_posix != NULL)
cwd.lock->acquire ();
cwd.posix = (char *) crealloc (cwd.posix, tlen + 1);
if (cwd.posix != NULL)
if (with_chroot && ischrootpath (temp))
{
strcpy (cwd_posix, temp + myself->rootlen);
strcpy (cwd.posix, temp + myself->rootlen);
if (!buf[0])
strcpy (buf, "/");
}
else
strcpy (cwd_posix, temp);
strcpy (cwd.posix, temp);
cwd.lock->release ();
if (tlen >= ulen)
{
/* len was too small */
set_errno (ERANGE);
}
set_errno (ERANGE); /* len was too small */
else
{
strcpy (buf, temp);
@ -2643,12 +2704,13 @@ chdir (const char *dir)
__seterrno ();
else
{
cwd.lock->acquire ();
/* Store new cache information */
free (cwd_win32);
cwd_win32 = strdup (path);
cfree (cwd.win32);
cwd.win32 = cstrdup (path);
char pathbuf[MAX_PATH];
(void) normalize_posix_path (cwd_posix, dir, pathbuf);
(void) normalize_posix_path (cwd.posix, dir, pathbuf);
/* Look for trailing path component consisting entirely of dots. This
is needed only in case of chdir since Windows simply ignores count
of dots > 2 here instead of returning an error code. Counts of dots
@ -2656,11 +2718,12 @@ chdir (const char *dir)
char *last_slash = strrchr (pathbuf, '/');
if (last_slash > pathbuf && strspn (last_slash + 1, ".") == strlen (last_slash + 1))
*last_slash = '\0';
free (cwd_posix);
cwd_posix = strdup (pathbuf);
cfree (cwd.posix);
cwd.posix = cstrdup (pathbuf);
cwd.lock->release ();
}
syscall_printf ("%d = chdir() cwd_posix '%s' native '%s'", res, cwd_posix, native_dir);
syscall_printf ("%d = chdir() cwd.posix '%s' native '%s'", res, cwd.posix, native_dir);
return res;
}

View File

@ -110,6 +110,11 @@ int __stdcall check_null_empty_path (const char *name);
const char * __stdcall find_exec (const char *name, path_conv& buf, const char *winenv = "PATH=",
int null_if_notfound = 0, const char **known_suffix = NULL);
void __stdcall cwd_init ();
char * __stdcall cwd_posix (char *);
char * __stdcall cwd_win32 (char *);
DWORD __stdcall cwd_hash ();
void __stdcall cwd_fixup_after_exec (char *, char *, DWORD);
/* Common macros for checking for invalid path names */

View File

@ -68,24 +68,13 @@ set_myself (pid_t pid, HANDLE h)
/* Initialize the process table entry for the current task.
This is not called for fork'd tasks, only exec'd ones. */
void __stdcall
pinfo_init (LPBYTE info)
pinfo_init (char **envp)
{
if (info != NULL)
if (envp)
{
/* The process was execed. Reuse entry from the original
owner of this pid. */
environ_init (0); /* Needs myself but affects calls below */
environ_init (envp);
/* spawn has already set up a pid structure for us so we'll use that */
myself->process_state |= PID_CYGPARENT;
/* Inherit file descriptor information from parent in info.
*/
LPBYTE b = fdtab.de_linearize_fd_array (info);
extern char title_buf[];
if (b && *b)
old_title = strcpy (title_buf, (char *)b);
}
else
{
@ -97,7 +86,7 @@ pinfo_init (LPBYTE info)
myself->ctty = -1;
myself->uid = USHRT_MAX;
environ_init (0); /* call after myself has been set up */
environ_init (NULL); /* call after myself has been set up */
}
debug_printf ("pid %d, pgid %d", myself->pid, myself->pgid);

View File

@ -72,10 +72,10 @@ public:
to `set_impersonation_token()'. */
HANDLE token;
BOOL impersonated;
uid_t orig_uid; /* Remains intact also after impersonation */
uid_t orig_gid; /* Ditto */
uid_t real_uid; /* Remains intact on seteuid, replaced by setuid */
gid_t real_gid; /* Ditto */
uid_t orig_uid; /* Remains intact also after impersonation */
uid_t orig_gid; /* Ditto */
uid_t real_uid; /* Remains intact on seteuid, replaced by setuid */
gid_t real_gid; /* Ditto */
/* Filled when chroot() is called by the process or one of it's parents.
Saved without trailing backslash. */
@ -163,6 +163,6 @@ cygwin_pid (pid_t pid)
return (pid_t) (os_being_run == winNT) ? pid : -(int) pid;
}
void __stdcall pinfo_init (BYTE *);
void __stdcall pinfo_init (char **);
void __stdcall set_myself (pid_t pid, HANDLE h = NULL);
extern pinfo myself;

View File

@ -48,36 +48,36 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
for (unsigned int i = 0; i < nfds; ++i)
if (!fdtab.not_open (fds[i].fd))
{
FD_SET (fds[i].fd, open_fds);
if (fds[i].events & POLLIN)
FD_SET (fds[i].fd, read_fds);
if (fds[i].events & POLLOUT)
FD_SET (fds[i].fd, write_fds);
if (fds[i].events & POLLPRI)
FD_SET (fds[i].fd, except_fds);
FD_SET (fds[i].fd, open_fds);
if (fds[i].events & POLLIN)
FD_SET (fds[i].fd, read_fds);
if (fds[i].events & POLLOUT)
FD_SET (fds[i].fd, write_fds);
if (fds[i].events & POLLPRI)
FD_SET (fds[i].fd, except_fds);
}
int ret = cygwin_select (max_fd + 1, read_fds, write_fds, except_fds,
timeout < 0 ? NULL : &tv);
timeout < 0 ? NULL : &tv);
for (unsigned int i = 0; i < nfds; ++i)
{
if (!FD_ISSET (fds[i].fd, open_fds))
fds[i].revents = POLLNVAL;
fds[i].revents = POLLNVAL;
else if (fdtab.not_open(fds[i].fd))
fds[i].revents = POLLHUP;
fds[i].revents = POLLHUP;
else if (ret < 0)
fds[i].revents = POLLERR;
fds[i].revents = POLLERR;
else
{
fds[i].revents = 0;
if (FD_ISSET (fds[i].fd, read_fds))
fds[i].revents |= POLLIN;
if (FD_ISSET (fds[i].fd, write_fds))
fds[i].revents |= POLLOUT;
if (FD_ISSET (fds[i].fd, except_fds))
fds[i].revents |= POLLPRI;
}
{
fds[i].revents = 0;
if (FD_ISSET (fds[i].fd, read_fds))
fds[i].revents |= POLLIN;
if (FD_ISSET (fds[i].fd, write_fds))
fds[i].revents |= POLLOUT;
if (FD_ISSET (fds[i].fd, except_fds))
fds[i].revents |= POLLPRI;
}
}
return ret;

View File

@ -208,11 +208,11 @@ get_registry_hive_path (const PSID psid, char *path)
key[0] = '\0';
if (!RegQueryValueExA (hkey, "ProfileImagePath", 0, &type,
(BYTE *)buf, (siz = 256, &siz)))
ExpandEnvironmentStringsA (buf, key, 256);
(BYTE *)buf, (siz = 256, &siz)))
ExpandEnvironmentStringsA (buf, key, 256);
RegCloseKey (hkey);
if (key[0])
return strcpy (path, key);
return strcpy (path, key);
}
return NULL;
}
@ -229,7 +229,7 @@ load_registry_hive (PSID psid)
return;
/* Check if user hive is already loaded. */
if (!RegOpenKeyExA (HKEY_USERS, convert_sid_to_string_sid (psid, sid),
0, KEY_READ, &hkey))
0, KEY_READ, &hkey))
{
debug_printf ("User registry hive for %s already exists", sid);
RegCloseKey (hkey);
@ -239,7 +239,7 @@ load_registry_hive (PSID psid)
{
strcat (path, "\\NTUSER.DAT");
if ((ret = RegLoadKeyA (HKEY_USERS, sid, path)) != ERROR_SUCCESS)
debug_printf ("Loading user registry hive for %s failed: %d", sid, ret);
debug_printf ("Loading user registry hive for %s failed: %d", sid, ret);
}
}

View File

@ -73,11 +73,11 @@ scandir (const char *dir,
{
closedir (dirp);
if (nl)
{
while (count > 0)
free (nl[--count]);
free (nl);
}
{
while (count > 0)
free (nl[--count]);
free (nl);
}
/* Ignore errors from closedir() and what not else. */
set_errno (prior_errno);
return -1;

File diff suppressed because it is too large Load Diff

View File

@ -841,10 +841,10 @@ peek_serial (select_record *s, int)
{
case WAIT_OBJECT_0:
if (!ClearCommError (h, &ev, &st))
{
debug_printf ("ClearCommError");
goto err;
}
{
debug_printf ("ClearCommError");
goto err;
}
else if (!st.cbInQue)
Sleep (to);
else

View File

@ -209,7 +209,7 @@ sec_user (PVOID sa_buf, PSID sid2, BOOL inherit)
PSECURITY_ATTRIBUTES psa = (PSECURITY_ATTRIBUTES) sa_buf;
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR)
((char *) sa_buf + sizeof (*psa));
((char *) sa_buf + sizeof (*psa));
PACL acl = (PACL) ((char *) sa_buf + sizeof (*psa) + sizeof (*psd));
char sid_buf[MAX_SID_LEN];
@ -221,46 +221,46 @@ sec_user (PVOID sa_buf, PSID sid2, BOOL inherit)
return inherit ? &sec_none_nih : &sec_none;
size_t acl_len = sizeof (ACL)
+ 4 * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD))
+ GetLengthSid (sid)
+ GetLengthSid (get_admin_sid ())
+ GetLengthSid (get_system_sid ())
+ GetLengthSid (get_creator_owner_sid ());
+ 4 * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD))
+ GetLengthSid (sid)
+ GetLengthSid (get_admin_sid ())
+ GetLengthSid (get_system_sid ())
+ GetLengthSid (get_creator_owner_sid ());
if (sid2)
acl_len += sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD)
+ GetLengthSid (sid2);
+ GetLengthSid (sid2);
if (! InitializeAcl (acl, acl_len, ACL_REVISION))
debug_printf("InitializeAcl %E");
if (! AddAccessAllowedAce (acl, ACL_REVISION,
SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
sid))
SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
sid))
debug_printf("AddAccessAllowedAce(%s) %E", getlogin());
if (! AddAccessAllowedAce (acl, ACL_REVISION,
SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
get_admin_sid ()))
SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
get_admin_sid ()))
debug_printf("AddAccessAllowedAce(admin) %E");
if (! AddAccessAllowedAce (acl, ACL_REVISION,
SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
get_system_sid ()))
SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
get_system_sid ()))
debug_printf("AddAccessAllowedAce(system) %E");
if (! AddAccessAllowedAce (acl, ACL_REVISION,
SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
get_creator_owner_sid ()))
SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
get_creator_owner_sid ()))
debug_printf("AddAccessAllowedAce(creator_owner) %E");
if (sid2)
if (! AddAccessAllowedAce (acl, ACL_REVISION,
SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
sid2))
SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
sid2))
debug_printf("AddAccessAllowedAce(sid2) %E");
if (! InitializeSecurityDescriptor (psd,
SECURITY_DESCRIPTOR_REVISION))
SECURITY_DESCRIPTOR_REVISION))
debug_printf("InitializeSecurityDescriptor %E");
/*

View File

@ -19,7 +19,6 @@ details. */
#include <wingdi.h>
#include <winuser.h>
#include <ctype.h>
#include <paths.h>
#include "cygerrno.h"
#include "fhandler.h"
#include "path.h"
@ -28,10 +27,9 @@ details. */
#include "sigproc.h"
#include "child_info.h"
#include "pinfo.h"
#include "cygheap.h"
#include "perthread.h"
extern BOOL allow_ntsec;
#define LINE_BUF_CHUNK (MAX_PATH * 2)
suffix_info std_suffixes[] =
@ -171,7 +169,6 @@ handle (int n, int direction)
*/
HANDLE NO_COPY hExeced = NULL;
DWORD NO_COPY exec_exit = 0;
int
iscmd (const char *argv0, const char *what)
@ -242,19 +239,66 @@ exec_fixup_after_fork ()
hexec_proc = NULL;
}
struct av
{
int argc;
int calloced;
private:
char **argv;
public:
av (int ac, const char * const *av) : argc (ac), calloced (0)
{
argv = (char **) cmalloc (HEAP_ARGV, (argc + 1) * sizeof (char *));
memcpy (argv, av, (argc + 1) * sizeof (char *));
}
~av ()
{
for (int i = 0; i < calloced; i++)
cfree (argv[i]);
cfree (argv);
}
int unshift (const char *what, int conv = 0);
operator char **() {return argv;}
};
int
av::unshift (const char *what, int conv)
{
char **av;
av = (char **) crealloc (argv, (argc + 2) * sizeof (char *));
if (!av)
return 0;
argv = av;
memmove (argv + 1, argv, (argc + 1) * sizeof (char *));
char buf[MAX_PATH + 1];
if (conv)
{
cygwin_conv_to_posix_path (what, buf);
char *p = strchr (buf, '\0') - 4;
if (p > buf && strcasematch (p, ".exe"))
*p = '\0';
what = buf;
}
*argv = cstrdup (what);
argc++;
calloced++;
return 1;
}
static int __stdcall
spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
const char *const envp[], int mode)
{
int i;
BOOL rc;
int argc;
pid_t cygpid;
hExeced = NULL;
MALLOC_CHECK;
// if (strstr (prog_arg, "dopath")) try_to_debug ();
if (prog_arg == NULL)
{
syscall_printf ("prog_arg is NULL");
@ -271,46 +315,69 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
return (-1);
}
/* CreateProcess takes one long string that is the command line (sigh).
We need to quote any argument that has whitespace or embedded "'s. */
for (argc = 0; argv[argc]; argc++)
/* nothing */;
char *real_path;
path_conv real_path_buf;
path_conv real_path;
linebuf one_line;
if (argc == 3 && argv[1][0] == '/' && argv[1][1] == 'c' &&
STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
child_info_spawn ciresrv;
si.lpReserved2 = (LPBYTE) &ciresrv;
si.cbReserved2 = sizeof (ciresrv);
HANDLE spr = NULL;
DWORD chtype;
if (mode != _P_OVERLAY && mode != _P_VFORK)
chtype = PROC_SPAWN;
else
{
spr = CreateEvent(&sec_all, TRUE, FALSE, NULL);
ProtectHandle (spr);
chtype = PROC_EXEC;
}
init_child_info (chtype, &ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1, spr);
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &ciresrv.parent, 0, 1,
DUPLICATE_SAME_ACCESS))
{
system_printf ("couldn't create handle to myself for child, %E");
return -1;
}
ciresrv.moreinfo = (cygheap_exec_info *) ccalloc (HEAP_EXEC, 1, sizeof (cygheap_exec_info));
ciresrv.moreinfo->old_title = old_title ? cstrdup (old_title) : NULL;
ciresrv.moreinfo->fds = fdtab;
ciresrv.moreinfo->nfds = fdtab.size;
/* CreateProcess takes one long string that is the command line (sigh).
We need to quote any argument that has whitespace or embedded "'s. */
int ac;
for (ac = 0; argv[ac]; ac++)
/* nothing */;
av newargv (ac, argv);
if (ac == 3 && argv[1][0] == '/' && argv[1][1] == 'c' &&
(iscmd (argv[0], "command.com") || iscmd (argv[0], "cmd.exe")))
{
one_line.add (argv[0]);
one_line.add (" ");
one_line.add (argv[1]);
one_line.add (" ");
real_path = NULL;
one_line.add (argv[2]);
strcpy (real_path_buf, argv[0]);
strcpy (real_path, argv[0]);
goto skip_arg_parsing;
}
real_path = real_path_buf;
const char *saved_prog_arg;
const char *newargv0, **firstarg;
const char *ext;
if ((ext = perhaps_suffix (prog_arg, real_path_buf)) == NULL)
if ((ext = perhaps_suffix (prog_arg, real_path)) == NULL)
{
set_errno (ENOENT);
return -1;
}
MALLOC_CHECK;
saved_prog_arg = prog_arg;
newargv0 = argv[0];
firstarg = &newargv0;
/* If the file name ends in either .exe, .com, .bat, or .cmd we assume
that it is NOT a script file */
@ -351,8 +418,7 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
if (buf[0] != '#' || buf[1] != '!')
{
strcpy (buf, "sh"); /* shell script without magic */
pgm = buf;
pgm = (char *) "/bin/sh";
ptr = buf + 2;
arg1 = NULL;
}
@ -379,87 +445,84 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
ptr = newptr - 1;
}
*ptr = '\0';
}
char buf2[MAX_PATH + 1];
/* pointers:
* pgm interpreter name
* arg1 optional string
* ptr end of string
*/
if (arg1)
newargv.unshift (arg1);
if (!arg1)
one_line.prepend (" ", 1);
else
{
one_line.prepend ("\" ", 2);
one_line.prepend (arg1, strlen (arg1));
one_line.prepend (" \"", 2);
}
find_exec (pgm, real_path_buf, "PATH=", 0, &ext);
cygwin_conv_to_posix_path (real_path, buf2);
one_line.prepend (buf2, strlen (buf2));
/* If script had absolute path, add it to script name now!
* This is necessary if script has been found via PATH.
* For example, /usr/local/bin/tkman started as "tkman":
* #!/usr/local/bin/wish -f
* ...
* We should run /usr/local/bin/wish -f /usr/local/bin/tkman,
* but not /usr/local/bin/wish -f tkman!
* We don't modify anything, if script has qulified path.
*/
if (firstarg)
*firstarg = saved_prog_arg;
debug_printf ("prog_arg '%s', copy '%s'", prog_arg, one_line.buf);
firstarg = NULL;
find_exec (pgm, real_path, "PATH=", 0, &ext);
newargv.unshift (real_path, 1);
}
for (; *argv; argv++)
{
char *p = NULL;
const char *a = newargv0 ?: *argv;
MALLOC_CHECK;
newargv0 = NULL;
int len = strlen (a);
if (len != 0 && !strpbrk (a, " \t\n\r\""))
one_line.add (a, len);
else
{
one_line.add ("\"", 1);
for (; (p = strpbrk (a, "\"\\")); a = ++p)
{
one_line.add (a, p - a);
if (*p == '\\' || *p == '"')
one_line.add ("\\", 1);
one_line.add (p, 1);
}
if (*a)
one_line.add (a);
one_line.add ("\"", 1);
}
MALLOC_CHECK;
one_line.add (" ", 1);
MALLOC_CHECK;
}
MALLOC_CHECK;
if (one_line.ix)
one_line.buf[one_line.ix - 1] = '\0';
if (real_path.iscygexec ())
for (int i = newargv.calloced; i < newargv.argc; i++)
newargv[i] = cstrdup (newargv[i]);
else
one_line.add ("", 1);
MALLOC_CHECK;
{
for (int i = 0; i < newargv.argc; i++)
{
char *p = NULL;
const char *a;
if (i >= newargv.calloced)
newargv[i] = cstrdup (newargv[i]);
a = newargv[i];
int len = strlen (a);
if (len != 0 && !strpbrk (a, " \t\n\r\""))
one_line.add (a, len);
else
{
one_line.add ("\"", 1);
for (; (p = strpbrk (a, "\"\\")); a = ++p)
{
one_line.add (a, p - a);
if (*p == '\\' || *p == '"')
one_line.add ("\\", 1);
one_line.add (p, 1);
}
if (*a)
one_line.add (a);
one_line.add ("\"", 1);
}
MALLOC_CHECK;
one_line.add (" ", 1);
MALLOC_CHECK;
}
MALLOC_CHECK;
if (one_line.ix)
one_line.buf[one_line.ix - 1] = '\0';
else
one_line.add ("", 1);
MALLOC_CHECK;
}
ciresrv.moreinfo->argc = newargv.argc;
ciresrv.moreinfo->argv = newargv;
/* FIXME: Should lock cwd access here. */
ciresrv.moreinfo->cwd_posix = cwd_posix (NULL);
ciresrv.moreinfo->cwd_win32 = cwd_win32 (NULL);
ciresrv.moreinfo->cwd_hash = cwd_hash ();
ciresrv.moreinfo->environ = (char **) cmalloc (HEAP_ARGV, envsize (envp, 1));
char **c;
const char * const *e;
for (c = ciresrv.moreinfo->environ, e = envp; *e; )
*c++ = cstrdup (*e++);
*c = NULL;
if (mode != _P_OVERLAY ||
!DuplicateHandle (hMainProc, myself.shared_handle (), hMainProc, &ciresrv.moreinfo->myself_pinfo, 0,
TRUE, DUPLICATE_SAME_ACCESS))
ciresrv.moreinfo->myself_pinfo = NULL;
skip_arg_parsing:
PROCESS_INFORMATION pi = {NULL, 0, 0, 0};
STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
si.lpReserved = NULL;
si.lpDesktop = NULL;
si.dwFlags = STARTF_USESTDHANDLES;
@ -470,53 +533,7 @@ skip_arg_parsing:
/* Pass fd table to a child */
MALLOC_CHECK;
int len = fdtab.linearize_fd_array (0, 0);
MALLOC_CHECK;
if (len == -1)
{
system_printf ("FATAL error in linearize_fd_array");
return -1;
}
int titlelen = 1 + (old_title && mode == _P_OVERLAY ? strlen (old_title) : 0);
si.cbReserved2 = len + titlelen + sizeof(child_info);
si.lpReserved2 = (LPBYTE) alloca (si.cbReserved2);
# define ciresrv ((child_info *)si.lpReserved2)
HANDLE spr = NULL;
DWORD chtype;
if (mode != _P_OVERLAY)
chtype = PROC_SPAWN;
else
{
spr = CreateEvent(&sec_all, TRUE, FALSE, NULL);
ProtectHandle (spr);
chtype = PROC_EXEC;
}
init_child_info (chtype, ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1, spr);
if (mode != _P_OVERLAY ||
!DuplicateHandle (hMainProc, myself.shared_handle (), hMainProc,
&ciresrv->myself_pinfo, 0,
TRUE, DUPLICATE_SAME_ACCESS))
ciresrv->myself_pinfo = NULL;
LPBYTE resrv = si.lpReserved2 + sizeof *ciresrv;
if (fdtab.linearize_fd_array (resrv, len) < 0)
{
system_printf ("FATAL error in second linearize_fd_array");
return -1;
}
if (titlelen > 1)
strcpy ((char *) resrv + len, old_title);
else
resrv[len] = '\0';
/* We print the translated program and arguments here so the user can see
what was done to it. */
syscall_printf ("spawn_guts (%s, %.132s)", real_path, one_line.buf);
syscall_printf ("spawn_guts (%s, %.132s)", (char *) real_path, one_line.buf);
int flags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED |
GetPriorityClass (hMainProc);
@ -525,7 +542,14 @@ skip_arg_parsing:
flags |= DETACHED_PROCESS;
/* Build windows style environment list */
char *envblock = winenv (envp, 0);
char *envblock;
if (real_path.iscygexec ())
envblock = NULL;
else
envblock = winenv (envp, 0);
ciresrv.cygheap = cygheap;
ciresrv.cygheap_max = cygheap_max;
/* Preallocated buffer for `sec_user' call */
char sa_buf[1024];
@ -533,9 +557,12 @@ skip_arg_parsing:
if (!hToken && myself->token != INVALID_HANDLE_VALUE)
hToken = myself->token;
/* FIXME: This leaves a handle to the process open so that the pid is not
duplicated. However, if a process execs another process two handles are
left open, which is unnecessary. */
if (mode == _P_OVERLAY && !hexec_proc &&
!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hexec_proc, 0,
TRUE, DUPLICATE_SAME_ACCESS))
TRUE, DUPLICATE_SAME_ACCESS))
system_printf ("couldn't save current process handle %p, %E", hMainProc);
if (hToken)
@ -561,22 +588,22 @@ skip_arg_parsing:
PSID sid = NULL;
DWORD ret_len;
if (GetTokenInformation (hToken, TokenUser,
(LPVOID) &tu, sizeof tu,
&ret_len))
sid = ((TOKEN_USER *) &tu)->User.Sid;
(LPVOID) &tu, sizeof tu,
&ret_len))
sid = ((TOKEN_USER *) &tu)->User.Sid;
else
system_printf ("GetTokenInformation: %E");
system_printf ("GetTokenInformation: %E");
/* Retrieve security attributes before setting psid to NULL
since it's value is needed by `sec_user'. */
since it's value is needed by `sec_user'. */
PSECURITY_ATTRIBUTES sec_attribs = allow_ntsec && sid
? sec_user (sa_buf, sid)
: &sec_all_nih;
? sec_user (sa_buf, sid)
: &sec_all_nih;
/* Remove impersonation */
uid_t uid = geteuid();
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (myself->orig_uid);
seteuid (myself->orig_uid);
/* Load users registry hive. */
load_registry_hive (sid);
@ -584,8 +611,8 @@ skip_arg_parsing:
rc = CreateProcessAsUser (hToken,
real_path, /* image name - with full path */
one_line.buf, /* what was passed to exec */
sec_attribs, /* process security attrs */
sec_attribs, /* thread security attrs */
sec_attribs, /* process security attrs */
sec_attribs, /* thread security attrs */
TRUE, /* inherit handles from parent */
flags,
envblock,/* environment */
@ -593,18 +620,18 @@ skip_arg_parsing:
&si,
&pi);
/* Restore impersonation. In case of _P_OVERLAY this isn't
allowed since it would overwrite child data. */
if (mode != _P_OVERLAY
&& myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (uid);
allowed since it would overwrite child data. */
if (mode != _P_OVERLAY && mode != _P_VFORK
&& myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (uid);
}
else
rc = CreateProcessA (real_path, /* image name - with full path */
one_line.buf, /* what was passed to exec */
/* process security attrs */
allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
/* thread security attrs */
allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
/* process security attrs */
allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
/* thread security attrs */
allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
TRUE, /* inherit handles from parent */
flags,
envblock,/* environment */
@ -613,17 +640,13 @@ skip_arg_parsing:
&pi);
MALLOC_CHECK;
free (envblock);
if (envblock)
free (envblock);
MALLOC_CHECK;
if (ciresrv->myself_pinfo)
CloseHandle (ciresrv->myself_pinfo);
/* Set errno now so that debugging messages from it appear before our
final debugging message [this is a general rule for debugging
messages]. */
if (!rc)
if (!rc)
{
if (spr)
@ -651,8 +674,8 @@ skip_arg_parsing:
if (mode == _P_OVERLAY)
{
close_all_files ();
strcpy (myself->progname, real_path_buf);
strcpy (myself->progname, real_path);
// close_all_files ();
proc_terminate ();
hExeced = pi.hProcess;
@ -676,8 +699,6 @@ skip_arg_parsing:
}
child->username[0] = '\0';
child->progname[0] = '\0';
// CGF FIXME -- need to do this? strcpy (child->progname, path);
// CGF FIXME -- need to do this? memcpy (child->username, myself->username, MAX_USER_NAME);
child->ppid = myself->pid;
child->uid = myself->uid;
child->gid = myself->gid;
@ -723,7 +744,7 @@ skip_arg_parsing:
DWORD res;
if (mode == _P_OVERLAY)
if (mode == _P_OVERLAY || mode == _P_VFORK)
{
BOOL exited;
@ -732,54 +753,45 @@ skip_arg_parsing:
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
res = 0;
DWORD timeout = INFINITE;
exec_exit = 1;
exited = FALSE;
MALLOC_CHECK;
for (int i = 0; i < 100; i++)
{
switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, timeout))
switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, INFINITE))
{
case WAIT_TIMEOUT:
syscall_printf ("WFMO timed out after signal");
if (WaitForSingleObject (pi.hProcess, 0) != WAIT_OBJECT_0)
{
sigproc_printf ("subprocess still alive after signal");
res = exec_exit;
}
else
{
sigproc_printf ("subprocess exited after signal");
case WAIT_OBJECT_0:
sigproc_printf ("subprocess exited");
if (!GetExitCodeProcess (pi.hProcess, &res))
res = exec_exit;
exited = TRUE;
}
if (nwait > 2)
if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0)
res |= EXIT_REPARENTING;
else if (!(res & EXIT_REPARENTING))
{
MALLOC_CHECK;
close_all_files ();
MALLOC_CHECK;
}
sigproc_printf ("subprocess exited");
if (!GetExitCodeProcess (pi.hProcess, &res))
res = 1;
exited = TRUE;
if (nwait <= 2 || mode != _P_OVERLAY)
/* nothing to do */;
else if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0)
goto reparent;
else if (!(res & EXIT_REPARENTING))
{
MALLOC_CHECK;
close_all_files ();
MALLOC_CHECK;
}
break;
case WAIT_OBJECT_0 + 1:
sigproc_printf ("signal arrived");
ResetEvent (signal_arrived);
continue;
case WAIT_OBJECT_0 + 2:
res = EXIT_REPARENTING;
MALLOC_CHECK;
ForceCloseHandle (spr);
MALLOC_CHECK;
if (!parent_alive)
if (mode == _P_OVERLAY)
{
nwait = 1;
sigproc_terminate ();
continue;
reparent:
res |= EXIT_REPARENTING;
close_all_files ();
if (!parent_alive)
{
nwait = 1;
sigproc_terminate ();
continue;
}
}
break;
case WAIT_FAILED:
@ -796,8 +808,7 @@ skip_arg_parsing:
break;
}
if (nwait > 2)
ForceCloseHandle (spr);
ForceCloseHandle (spr);
sigproc_printf ("res = %x", res);
@ -813,18 +824,19 @@ skip_arg_parsing:
/* nothing */;
else
{
int rc;
HANDLE hP = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
parent->dwProcessId);
sigproc_printf ("parent handle %p, pid %d", hP, parent->dwProcessId);
if (hP == NULL && GetLastError () == ERROR_INVALID_PARAMETER)
res = 1;
rc = 1;
else if (hP)
{
ProtectHandle (hP);
res = DuplicateHandle (hMainProc, pi.hProcess, hP,
&myself->hProcess, 0, FALSE,
DUPLICATE_SAME_ACCESS);
sigproc_printf ("Dup hP %d", res);
rc = DuplicateHandle (hMainProc, pi.hProcess, hP,
&myself->hProcess, 0, FALSE,
DUPLICATE_SAME_ACCESS);
sigproc_printf ("Dup hP %d", rc);
ForceCloseHandle (hP);
}
if (!res)
@ -837,7 +849,6 @@ skip_arg_parsing:
system_printf ("myself->hProcess %x", myself->hProcess);
}
}
res = EXIT_REPARENTING;
ForceCloseHandle1 (hExeced, childhProc);
hExeced = INVALID_HANDLE_VALUE;
}
@ -848,15 +859,26 @@ skip_arg_parsing:
}
MALLOC_CHECK;
do_exit (res | EXIT_NOCLOSEALL);
if (mode == _P_OVERLAY)
do_exit (res | EXIT_NOCLOSEALL);
}
if (mode == _P_WAIT)
waitpid (cygpid, (int *) &res, 0);
else if (mode == _P_DETACH)
res = 0; /* Lose all memory of this child. */
else if ((mode == _P_NOWAIT) || (mode == _P_NOWAITO))
res = cygpid;
switch (mode)
{
case _P_WAIT:
waitpid (cygpid, (int *) &res, 0);
break;
case _P_DETACH:
res = 0; /* Lose all memory of this child. */
break;
case _P_NOWAIT:
case _P_NOWAITO:
case _P_VFORK:
res = cygpid;
break;
default:
break;
}
return (int) res;
}
@ -889,29 +911,30 @@ _spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv,
switch (mode)
{
case _P_OVERLAY:
/* We do not pass _P_SEARCH_PATH here. execve doesn't search PATH.*/
/* Just act as an exec if _P_OVERLAY set. */
spawn_guts (hToken, path, argv, envp, mode);
/* Errno should be set by spawn_guts. */
ret = -1;
break;
case _P_NOWAIT:
case _P_NOWAITO:
case _P_WAIT:
case _P_DETACH:
subproc_init ();
ret = spawn_guts (hToken, path, argv, envp, mode);
if (vf && ret > 0)
{
vf->pid = ret;
longjmp (vf->j, 1);
}
break;
default:
set_errno (EINVAL);
ret = -1;
break;
case _P_OVERLAY:
/* We do not pass _P_SEARCH_PATH here. execve doesn't search PATH.*/
/* Just act as an exec if _P_OVERLAY set. */
spawn_guts (hToken, path, argv, envp, mode);
/* Errno should be set by spawn_guts. */
ret = -1;
break;
case _P_VFORK:
case _P_NOWAIT:
case _P_NOWAITO:
case _P_WAIT:
case _P_DETACH:
subproc_init ();
ret = spawn_guts (hToken, path, argv, envp, 0);
if (vf && ret > 0)
{
vf->pid = ret;
longjmp (vf->j, 1);
}
break;
default:
set_errno (EINVAL);
ret = -1;
break;
}
return ret;
}

View File

@ -21,7 +21,6 @@ details. */
#include <sys/uio.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <winnls.h>
#include <lmcons.h> /* for UNLEN */
#include "cygerrno.h"
@ -32,6 +31,7 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include <unistd.h>
extern BOOL allow_ntsec;
@ -1015,8 +1015,8 @@ stat_worker (const char *caller, const char *name, struct stat *buf,
debug_printf ("%s (%s, %p)", caller, name, buf);
path_conv real_path (name, (nofollow ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW) | PC_FULL,
stat_suffixes);
path_conv real_path (name, (nofollow ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW) |
PC_FULL, stat_suffixes);
if (real_path.error)
{
@ -1421,6 +1421,16 @@ pathconf (const char *file, int v)
}
}
extern "C" char *
ttyname (int fd)
{
if (fdtab.not_open (fd) || !fdtab[fd]->is_tty ())
{
return 0;
}
return (char *)(fdtab[fd]->ttyname ());
}
extern "C" char *
ctermid (char *str)
{
@ -1434,20 +1444,8 @@ ctermid (char *str)
return str;
}
extern "C"
char *
ttyname (int fd)
{
if (fdtab.not_open (fd) || !fdtab[fd]->is_tty ())
{
return 0;
}
return (char *)(fdtab[fd]->ttyname ());
}
/* Tells stdio if it should do the cr/lf conversion for this file */
extern "C" int _cygwin_istext_for_stdio (int fd);
int
extern "C" int
_cygwin_istext_for_stdio (int fd)
{
syscall_printf("_cygwin_istext_for_stdio (%d)\n", fd);
@ -1570,8 +1568,7 @@ setmode (int fd, int mode)
}
/* ftruncate: P96 5.6.7.1 */
extern "C"
int
extern "C" int
ftruncate (int fd, off_t length)
{
int res = -1;
@ -1609,8 +1606,7 @@ ftruncate (int fd, off_t length)
/* truncate: Provided by SVR4 and 4.3+BSD. Not part of POSIX.1 or XPG3 */
/* FIXME: untested */
extern "C"
int
extern "C" int
truncate (const char *pathname, off_t length)
{
int fd;
@ -1632,8 +1628,7 @@ truncate (const char *pathname, off_t length)
return res;
}
extern "C"
long
extern "C" long
get_osfhandle (int fd)
{
long res = -1;
@ -1651,8 +1646,7 @@ get_osfhandle (int fd)
return res;
}
extern "C"
int
extern "C" int
statfs (const char *fname, struct statfs *sfs)
{
if (!sfs)
@ -1692,8 +1686,7 @@ statfs (const char *fname, struct statfs *sfs)
return 0;
}
extern "C"
int
extern "C" int
fstatfs (int fd, struct statfs *sfs)
{
if (fdtab.not_open (fd))
@ -1706,8 +1699,7 @@ fstatfs (int fd, struct statfs *sfs)
}
/* setpgid: POSIX 4.3.3.1 */
extern "C"
int
extern "C" int
setpgid (pid_t pid, pid_t pgid)
{
int res = -1;
@ -1746,8 +1738,7 @@ out:
return res;
}
extern "C"
pid_t
extern "C" pid_t
getpgid (pid_t pid)
{
if (pid == 0)
@ -1762,22 +1753,19 @@ getpgid (pid_t pid)
return p->pgid;
}
extern "C"
int
extern "C" int
setpgrp (void)
{
return setpgid (0, 0);
}
extern "C"
pid_t
extern "C" pid_t
getpgrp (void)
{
return getpgid (0);
}
extern "C"
char *
extern "C" char *
ptsname (int fd)
{
if (fdtab.not_open (fd))
@ -1789,8 +1777,7 @@ ptsname (int fd)
}
/* FIXME: what is this? */
extern "C"
int
extern "C" int
regfree ()
{
return 0;
@ -1802,8 +1789,7 @@ regfree ()
Although mknod hasn't been implemented yet, some GNU tools (e.g. the
fileutils) assume its existence so we must provide a stub that always
fails. */
extern "C"
int
extern "C" int
mknod ()
{
set_errno (ENOSYS);
@ -1811,8 +1797,7 @@ mknod ()
}
/* setgid: POSIX 4.2.2.1 */
extern "C"
int
extern "C" int
setgid (gid_t gid)
{
int ret = setegid (gid);
@ -1822,8 +1807,7 @@ setgid (gid_t gid)
}
/* setuid: POSIX 4.2.2.1 */
extern "C"
int
extern "C" int
setuid (uid_t uid)
{
int ret = seteuid (uid);
@ -1836,8 +1820,7 @@ setuid (uid_t uid)
extern char *internal_getlogin (_pinfo *pi);
/* seteuid: standards? */
extern "C"
int
extern "C" int
seteuid (uid_t uid)
{
if (os_being_run == winNT)

View File

@ -196,7 +196,7 @@ MTinterface::Find (void *_value, int (*comp) (void *, void *), register int &_in
{
current = _list->items[_index];
if (current->used && comp (current, _value))
break;
break;
current = NULL;
}
return current;
@ -211,7 +211,7 @@ MTinterface::Find (MTitem & _item, MTList * _list)
{
current = _list->items[_index];
if (current->used && current == &_item)
break;
break;
}
return (_index == _list->index ? -1 : _index);
};
@ -481,7 +481,7 @@ thread_init_wrapper (void *_arg)
struct _reent local_clib;
struct sigaction _sigs[NSIG];
sigset_t _sig_mask; /* one set for everything to ignore. */
sigset_t _sig_mask; /* one set for everything to ignore. */
LONG _sigtodo[NSIG + __SIGOFFSET];
// setup signal structures
@ -520,7 +520,7 @@ thread_init_wrapper (void *_arg)
// FIX ME : cleanup code
// thread->used = false; // release thread entry
// thread->used = false; // release thread entry
thread->return_ptr = ret;
ExitThread (0);
}
@ -595,7 +595,7 @@ __pthread_join (pthread_t * thread, void **return_val)
if (item->joinable == 'N')
{
if (return_val)
*return_val = NULL;
*return_val = NULL;
return EINVAL;
}
else
@ -603,7 +603,7 @@ __pthread_join (pthread_t * thread, void **return_val)
item->joinable = 'N';
WaitForSingleObject ((HANDLE)*thread, INFINITE);
if (return_val)
*return_val = item->return_ptr;
*return_val = item->return_ptr;
}/* End if*/
return 0;
@ -651,7 +651,7 @@ __pthread_continue (pthread_t * thread)
return ESRCH;
if (item->suspended == true)
ResumeThread ((HANDLE)*thread);
ResumeThread ((HANDLE)*thread);
item->suspended = false;
return 0;
@ -994,4 +994,4 @@ extern "C"
}
}
#endif // MT_SAFE
#endif // MT_SAFE

View File

@ -74,9 +74,6 @@ struct _winsup_t
/* path.cc */
struct mntent _ret;
char *_cwd_win32;
char *_cwd_posix;
unsigned long _cwd_hash;
int _iteration;
/* strerror */
@ -306,6 +303,6 @@ int __sem_post (sem_t * sem);
};
#endif // MT_SAFE
#endif // MT_SAFE
#endif // _CYGNUS_THREADS_
#endif // _CYGNUS_THREADS_

View File

@ -40,130 +40,130 @@ internal_getlogin (_pinfo *pi)
/* First trying to get logon info from environment */
if ((env = getenv ("USERNAME")) != NULL)
un = env;
un = env;
if ((env = getenv ("LOGONSERVER")) != NULL)
strcpy (pi->logsrv, env + 2); /* filter leading double backslashes */
strcpy (pi->logsrv, env + 2); /* filter leading double backslashes */
if ((env = getenv ("USERDOMAIN")) != NULL)
strcpy (pi->domain, env);
strcpy (pi->domain, env);
/* Trust only if usernames are identical */
if (un && strcasematch (pi->username, un)
&& pi->domain[0] && pi->logsrv[0])
debug_printf ("Domain: %s, Logon Server: %s", pi->domain, pi->logsrv);
&& pi->domain[0] && pi->logsrv[0])
debug_printf ("Domain: %s, Logon Server: %s", pi->domain, pi->logsrv);
/* If that failed, try to get that info from NetBIOS */
else if (!NetWkstaUserGetInfo (NULL, 1, (LPBYTE *)&wui))
{
sys_wcstombs (pi->username, wui->wkui1_username, MAX_USER_NAME);
sys_wcstombs (pi->logsrv, wui->wkui1_logon_server, MAX_HOST_NAME);
sys_wcstombs (pi->domain, wui->wkui1_logon_domain,
MAX_COMPUTERNAME_LENGTH + 1);
/* Save values in environment */
if (!strcasematch (pi->username, "SYSTEM")
&& pi->domain[0] && pi->logsrv[0])
{
LPUSER_INFO_3 ui = NULL;
WCHAR wbuf[MAX_HOST_NAME + 2];
{
sys_wcstombs (pi->username, wui->wkui1_username, MAX_USER_NAME);
sys_wcstombs (pi->logsrv, wui->wkui1_logon_server, MAX_HOST_NAME);
sys_wcstombs (pi->domain, wui->wkui1_logon_domain,
MAX_COMPUTERNAME_LENGTH + 1);
/* Save values in environment */
if (!strcasematch (pi->username, "SYSTEM")
&& pi->domain[0] && pi->logsrv[0])
{
LPUSER_INFO_3 ui = NULL;
WCHAR wbuf[MAX_HOST_NAME + 2];
strcat (strcpy (buf, "\\\\"), pi->logsrv);
setenv ("USERNAME", pi->username, 1);
setenv ("LOGONSERVER", buf, 1);
setenv ("USERDOMAIN", pi->domain, 1);
/* HOMEDRIVE and HOMEPATH are wrong most of the time, too,
after changing user context! */
sys_mbstowcs (wbuf, buf, MAX_HOST_NAME + 2);
if (!NetUserGetInfo (NULL, wui->wkui1_username, 3, (LPBYTE *)&ui)
|| !NetUserGetInfo (wbuf,wui->wkui1_username,3,(LPBYTE *)&ui))
{
sys_wcstombs (buf, ui->usri3_home_dir, MAX_PATH);
if (!buf[0])
{
sys_wcstombs (buf, ui->usri3_home_dir_drive, MAX_PATH);
if (buf[0])
strcat (buf, "\\");
else
{
env = getenv ("SYSTEMDRIVE");
if (env && *env)
strcat (strcpy (buf, env), "\\");
else
GetSystemDirectoryA (buf, MAX_PATH);
}
}
setenv ("HOMEPATH", buf + 2, 1);
buf[2] = '\0';
setenv ("HOMEDRIVE", buf, 1);
NetApiBufferFree (ui);
}
}
debug_printf ("Domain: %s, Logon Server: %s, Windows Username: %s",
pi->domain, pi->logsrv, pi->username);
NetApiBufferFree (wui);
}
strcat (strcpy (buf, "\\\\"), pi->logsrv);
setenv ("USERNAME", pi->username, 1);
setenv ("LOGONSERVER", buf, 1);
setenv ("USERDOMAIN", pi->domain, 1);
/* HOMEDRIVE and HOMEPATH are wrong most of the time, too,
after changing user context! */
sys_mbstowcs (wbuf, buf, MAX_HOST_NAME + 2);
if (!NetUserGetInfo (NULL, wui->wkui1_username, 3, (LPBYTE *)&ui)
|| !NetUserGetInfo (wbuf,wui->wkui1_username,3,(LPBYTE *)&ui))
{
sys_wcstombs (buf, ui->usri3_home_dir, MAX_PATH);
if (!buf[0])
{
sys_wcstombs (buf, ui->usri3_home_dir_drive, MAX_PATH);
if (buf[0])
strcat (buf, "\\");
else
{
env = getenv ("SYSTEMDRIVE");
if (env && *env)
strcat (strcpy (buf, env), "\\");
else
GetSystemDirectoryA (buf, MAX_PATH);
}
}
setenv ("HOMEPATH", buf + 2, 1);
buf[2] = '\0';
setenv ("HOMEDRIVE", buf, 1);
NetApiBufferFree (ui);
}
}
debug_printf ("Domain: %s, Logon Server: %s, Windows Username: %s",
pi->domain, pi->logsrv, pi->username);
NetApiBufferFree (wui);
}
if (allow_ntsec)
{
HANDLE ptok = pi->token; /* Which is INVALID_HANDLE_VALUE if no
impersonation took place. */
DWORD siz;
char tu[1024];
int ret = 0;
/* Try to get the SID either from already impersonated token
or from current process first. To differ that two cases is
important, because you can't rely on the user information
in a process token of a currently impersonated process. */
if (ptok == INVALID_HANDLE_VALUE
&& !OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok))
debug_printf ("OpenProcessToken(): %E\n");
else if (!GetTokenInformation (ptok, TokenUser, (LPVOID) &tu,
sizeof tu, &siz))
debug_printf ("GetTokenInformation(): %E");
else if (!(ret = CopySid (MAX_SID_LEN, (PSID) pi->psid,
((TOKEN_USER *) &tu)->User.Sid)))
debug_printf ("Couldn't retrieve SID from access token!");
/* Close token only if it's a result from OpenProcessToken(). */
if (ptok != INVALID_HANDLE_VALUE && pi->token == INVALID_HANDLE_VALUE)
CloseHandle (ptok);
{
HANDLE ptok = pi->token; /* Which is INVALID_HANDLE_VALUE if no
impersonation took place. */
DWORD siz;
char tu[1024];
int ret = 0;
/* Try to get the SID either from already impersonated token
or from current process first. To differ that two cases is
important, because you can't rely on the user information
in a process token of a currently impersonated process. */
if (ptok == INVALID_HANDLE_VALUE
&& !OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok))
debug_printf ("OpenProcessToken(): %E\n");
else if (!GetTokenInformation (ptok, TokenUser, (LPVOID) &tu,
sizeof tu, &siz))
debug_printf ("GetTokenInformation(): %E");
else if (!(ret = CopySid (MAX_SID_LEN, (PSID) pi->psid,
((TOKEN_USER *) &tu)->User.Sid)))
debug_printf ("Couldn't retrieve SID from access token!");
/* Close token only if it's a result from OpenProcessToken(). */
if (ptok != INVALID_HANDLE_VALUE && pi->token == INVALID_HANDLE_VALUE)
CloseHandle (ptok);
/* If that failes, try to get the SID from localhost. This can only
be done if a domain is given because there's a chance that a local
and a domain user may have the same name. */
if (!ret && pi->domain[0])
{
/* Concat DOMAIN\USERNAME for the next lookup */
strcat (strcat (strcpy (buf, pi->domain), "\\"), pi->username);
if (!(ret = lookup_name (buf, NULL, (PSID) pi->psid)))
debug_printf ("Couldn't retrieve SID locally!");
}
/* If that failes, try to get the SID from localhost. This can only
be done if a domain is given because there's a chance that a local
and a domain user may have the same name. */
if (!ret && pi->domain[0])
{
/* Concat DOMAIN\USERNAME for the next lookup */
strcat (strcat (strcpy (buf, pi->domain), "\\"), pi->username);
if (!(ret = lookup_name (buf, NULL, (PSID) pi->psid)))
debug_printf ("Couldn't retrieve SID locally!");
}
/* If that failes, too, as a last resort try to get the SID from
the logon server. */
if (!ret && !(ret = lookup_name(pi->username, pi->logsrv,
(PSID)pi->psid)))
debug_printf ("Couldn't retrieve SID from '%s'!", pi->logsrv);
/* If that failes, too, as a last resort try to get the SID from
the logon server. */
if (!ret && !(ret = lookup_name(pi->username, pi->logsrv,
(PSID)pi->psid)))
debug_printf ("Couldn't retrieve SID from '%s'!", pi->logsrv);
/* If we have a SID, try to get the corresponding Cygwin user name
which can be different from the Windows user name. */
if (ret)
{
struct passwd *pw;
char psidbuf[MAX_SID_LEN];
PSID psid = (PSID) psidbuf;
/* If we have a SID, try to get the corresponding Cygwin user name
which can be different from the Windows user name. */
if (ret)
{
struct passwd *pw;
char psidbuf[MAX_SID_LEN];
PSID psid = (PSID) psidbuf;
pi->use_psid = 1;
if (!strcasematch (pi->username, "SYSTEM")
&& pi->domain[0] && pi->logsrv[0])
{
if (get_registry_hive_path (pi->psid, buf))
setenv ("USERPROFILE", buf, 1);
}
while ((pw = getpwent ()) != NULL)
if (get_pw_sid (psid, pw) && EqualSid (pi->psid, psid))
{
strcpy (pi->username, pw->pw_name);
break;
}
endpwent ();
}
}
pi->use_psid = 1;
if (!strcasematch (pi->username, "SYSTEM")
&& pi->domain[0] && pi->logsrv[0])
{
if (get_registry_hive_path (pi->psid, buf))
setenv ("USERPROFILE", buf, 1);
}
while ((pw = getpwent ()) != NULL)
if (get_pw_sid (psid, pw) && EqualSid (pi->psid, psid))
{
strcpy (pi->username, pw->pw_name);
break;
}
endpwent ();
}
}
}
debug_printf ("Cygwins Username: %s", pi->username);
return pi->username;
@ -187,13 +187,13 @@ uinfo_init ()
if (myself->uid == USHRT_MAX)
if ((p = getpwnam (username = internal_getlogin (myself))) != NULL)
{
myself->uid = p->pw_uid;
myself->gid = p->pw_gid;
myself->uid = p->pw_uid;
myself->gid = p->pw_gid;
}
else
{
myself->uid = DEFAULT_UID;
myself->gid = DEFAULT_GID;
myself->uid = DEFAULT_UID;
myself->gid = DEFAULT_GID;
}
/* Real and effective uid/gid are always identical on process start up.
This is at least true for NT/W2K. */

View File

@ -1,6 +1,6 @@
/* winsup.h: main Cygwin header file.
Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
Copyright 1996, 1997, 1998, 1999, 2000 Red Hat, Inc.
This file is part of Cygwin.
@ -83,9 +83,9 @@ extern os_type os_being_run;
extern int dynamically_loaded;
#define sys_wcstombs(tgt,src,len) \
WideCharToMultiByte(CP_ACP,0,(src),-1,(tgt),(len),NULL,NULL)
WideCharToMultiByte(CP_ACP,0,(src),-1,(tgt),(len),NULL,NULL)
#define sys_mbstowcs(tgt,src,len) \
MultiByteToWideChar(CP_ACP,0,(src),-1,(tgt),(len))
MultiByteToWideChar(CP_ACP,0,(src),-1,(tgt),(len))
#include <cygwin/version.h>
@ -200,11 +200,7 @@ extern "C" int dll_noncygwin_dllcrt0 (HMODULE, per_process *);
extern "C" void __stdcall do_exit (int) __attribute__ ((noreturn));
/* Initialize the environment */
void environ_init (int);
/* Heap management. */
void heap_init (void);
void malloc_init (void);
void environ_init (char **);
/* UID/GID */
void uinfo_init (void);
@ -236,7 +232,7 @@ extern int cygwin_finished_initializing;
/* File manipulation */
int __stdcall set_process_privileges ();
int __stdcall get_file_attribute (int, const char *, int *,
uid_t * = NULL, gid_t * = NULL);
uid_t * = NULL, gid_t * = NULL);
int __stdcall set_file_attribute (int, const char *, int);
int __stdcall set_file_attribute (int, const char *, uid_t, gid_t, int, const char *);
void __stdcall set_std_handle (int);
@ -258,6 +254,7 @@ extern "C" char *__stdcall rootdir (char *full_path);
void __stdcall mark (const char *, int);
#define _P_VFORK 0
extern "C" int _spawnve (HANDLE hToken, int mode, const char *path,
const char *const *argv, const char *const *envp);
@ -278,12 +275,6 @@ char *__stdcall strcasestr (const char *searchee, const char *lookfor);
void __stdcall totimeval (struct timeval *dst, FILETIME * src, int sub, int flag);
long __stdcall to_time_t (FILETIME * ptr);
/* pinfo table manipulation */
#ifndef lock_pinfo_for_update
int __stdcall lock_pinfo_for_update (DWORD timeout);
#endif
void unlock_pinfo (void);
/* Retrieve a security descriptor that allows all access */
SECURITY_DESCRIPTOR *__stdcall get_null_sd (void);
@ -375,6 +366,7 @@ void __stdcall update_envptrs ();
char * __stdcall winenv (const char * const *, int);
extern char **__cygwin_environ, ***main_environ;
extern "C" char __stdcall **cur_environ ();
int __stdcall envsize (const char * const *, int debug_print = 0);
/* The title on program start. */
extern char *old_title;