#define Win32_Winsock
#endif
#include <windows.h>
+#include <shellapi.h>
#include <winnt.h>
#include <io.h>
}
DllExport int
-win32_stat(const char *path, struct stat *buffer)
+win32_stat(const char *path, struct stat *sbuf)
{
dTHXo;
- char t[MAX_PATH+1];
+ char buffer[MAX_PATH+1];
int l = strlen(path);
int res;
WCHAR wbuffer[MAX_PATH+1];
+ WCHAR* pwbuffer;
HANDLE handle;
int nlink = 1;
/* FindFirstFile() and stat() are buggy with a trailing
* backslash, so change it to a forward slash :-( */
case '\\':
- strncpy(t, path, l-1);
- t[l - 1] = '/';
- t[l] = '\0';
- path = t;
+ strncpy(buffer, path, l-1);
+ buffer[l - 1] = '/';
+ buffer[l] = '\0';
+ path = buffer;
break;
/* FindFirstFile() is buggy with "x:", so add a dot :-( */
case ':':
if (l == 2 && isALPHA(path[0])) {
- t[0] = path[0]; t[1] = ':'; t[2] = '.'; t[3] = '\0';
+ buffer[0] = path[0];
+ buffer[1] = ':';
+ buffer[2] = '.';
+ buffer[3] = '\0';
l = 3;
- path = t;
+ path = buffer;
}
break;
}
/* This also gives us an opportunity to determine the number of links. */
if (USING_WIDE()) {
A2WHELPER(path, wbuffer, sizeof(wbuffer));
- wcscpy(wbuffer, PerlDir_mapW(wbuffer));
- handle = CreateFileW(wbuffer, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+ pwbuffer = PerlDir_mapW(wbuffer);
+ handle = CreateFileW(pwbuffer, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
}
else {
path = PerlDir_mapA(path);
+ l = strlen(path);
handle = CreateFileA(path, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
}
if (handle != INVALID_HANDLE_VALUE) {
CloseHandle(handle);
}
- /* wbuffer or path will be mapped correctly above */
+ /* pwbuffer or path will be mapped correctly above */
if (USING_WIDE()) {
- res = _wstat(wbuffer, (struct _stat *)buffer);
+ res = _wstat(pwbuffer, (struct _stat *)sbuf);
}
else {
- res = stat(path, buffer);
+ res = stat(path, sbuf);
}
- buffer->st_nlink = nlink;
+ sbuf->st_nlink = nlink;
if (res < 0) {
/* CRT is buggy on sharenames, so make sure it really isn't.
* XXX using GetFileAttributesEx() will enable us to set
- * buffer->st_*time (but note that's not available on the
+ * sbuf->st_*time (but note that's not available on the
* Windows of 1995) */
DWORD r;
if (USING_WIDE()) {
- r = GetFileAttributesW(wbuffer);
+ r = GetFileAttributesW(pwbuffer);
}
else {
r = GetFileAttributesA(path);
}
if (r != 0xffffffff && (r & FILE_ATTRIBUTE_DIRECTORY)) {
- /* buffer may still contain old garbage since stat() failed */
- Zero(buffer, 1, struct stat);
- buffer->st_mode = S_IFDIR | S_IREAD;
+ /* sbuf may still contain old garbage since stat() failed */
+ Zero(sbuf, 1, struct stat);
+ sbuf->st_mode = S_IFDIR | S_IREAD;
errno = 0;
if (!(r & FILE_ATTRIBUTE_READONLY))
- buffer->st_mode |= S_IWRITE | S_IEXEC;
+ sbuf->st_mode |= S_IWRITE | S_IEXEC;
return 0;
}
}
{
/* The drive can be inaccessible, some _stat()s are buggy */
if (USING_WIDE()
- ? !GetVolumeInformationW(wbuffer,NULL,0,NULL,NULL,NULL,NULL,0)
+ ? !GetVolumeInformationW(pwbuffer,NULL,0,NULL,NULL,NULL,NULL,0)
: !GetVolumeInformationA(path,NULL,0,NULL,NULL,NULL,NULL,0)) {
errno = ENOENT;
return -1;
}
}
#ifdef __BORLANDC__
- if (S_ISDIR(buffer->st_mode))
- buffer->st_mode |= S_IWRITE | S_IEXEC;
- else if (S_ISREG(buffer->st_mode)) {
+ if (S_ISDIR(sbuf->st_mode))
+ sbuf->st_mode |= S_IWRITE | S_IEXEC;
+ else if (S_ISREG(sbuf->st_mode)) {
+ int perms;
if (l >= 4 && path[l-4] == '.') {
const char *e = path + l - 3;
if (strnicmp(e,"exe",3)
&& strnicmp(e,"bat",3)
&& strnicmp(e,"com",3)
&& (IsWin95() || strnicmp(e,"cmd",3)))
- buffer->st_mode &= ~S_IEXEC;
+ sbuf->st_mode &= ~S_IEXEC;
else
- buffer->st_mode |= S_IEXEC;
+ sbuf->st_mode |= S_IEXEC;
}
else
- buffer->st_mode &= ~S_IEXEC;
+ sbuf->st_mode &= ~S_IEXEC;
+ /* Propagate permissions to _group_ and _others_ */
+ perms = sbuf->st_mode & (S_IREAD|S_IWRITE|S_IEXEC);
+ sbuf->st_mode |= (perms>>3) | (perms>>6);
}
#endif
}
if (USING_WIDE()) {
WCHAR wBuffer[MAX_PATH+1];
+ WCHAR* pwBuffer;
A2WHELPER(filename, wBuffer, sizeof(wBuffer));
- wcscpy(wBuffer, PerlDir_mapW(wBuffer));
- attrs = GetFileAttributesW(wBuffer);
+ pwBuffer = PerlDir_mapW(wBuffer);
+ attrs = GetFileAttributesW(pwBuffer);
if (attrs == 0xFFFFFFFF)
goto fail;
if (attrs & FILE_ATTRIBUTE_READONLY) {
- (void)SetFileAttributesW(wBuffer, attrs & ~FILE_ATTRIBUTE_READONLY);
- ret = _wunlink(wBuffer);
+ (void)SetFileAttributesW(pwBuffer, attrs & ~FILE_ATTRIBUTE_READONLY);
+ ret = _wunlink(pwBuffer);
if (ret == -1)
- (void)SetFileAttributesW(wBuffer, attrs);
+ (void)SetFileAttributesW(pwBuffer, attrs);
}
else
- ret = _wunlink(wBuffer);
+ ret = _wunlink(pwBuffer);
}
else {
filename = PerlDir_mapA(filename);
FILETIME ftWrite;
struct utimbuf TimeBuffer;
WCHAR wbuffer[MAX_PATH+1];
+ WCHAR* pwbuffer;
int rc;
if (USING_WIDE()) {
A2WHELPER(filename, wbuffer, sizeof(wbuffer));
- wcscpy(wbuffer, PerlDir_mapW(wbuffer));
- rc = _wutime(wbuffer, (struct _utimbuf*)times);
+ pwbuffer = PerlDir_mapW(wbuffer);
+ rc = _wutime(pwbuffer, (struct _utimbuf*)times);
}
else {
filename = PerlDir_mapA(filename);
/* This will (and should) still fail on readonly files */
if (USING_WIDE()) {
- handle = CreateFileW(wbuffer, GENERIC_READ | GENERIC_WRITE,
+ handle = CreateFileW(pwbuffer, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
}
return -1;
}
+#ifndef PERL_OBJECT
+
static UINT timerid = 0;
static VOID CALLBACK TimerProc(HWND win, UINT msg, UINT id, DWORD time)
timerid=0;
sighandler(14);
}
+#endif /* !PERL_OBJECT */
DllExport unsigned int
win32_alarm(unsigned int sec)
{
+#ifndef PERL_OBJECT
/*
* the 'obvious' implentation is SetTimer() with a callback
* which does whatever receiving SIGALRM would do
timerid=0;
}
}
+#endif /* !PERL_OBJECT */
return 0;
}
#ifdef USE_FIXED_OSFHANDLE
#define FOPEN 0x01 /* file handle open */
+#define FNOINHERIT 0x10 /* file handle opened O_NOINHERIT */
#define FAPPEND 0x20 /* file handle opened O_APPEND */
#define FDEV 0x40 /* file handle refers to device */
#define FTEXT 0x80 /* file handle is in text mode */
/* create an ioinfo entry, kill its handle, and steal the entry */
-static int _alloc_osfhnd()
+static int
+_alloc_osfhnd(void)
{
HANDLE hF = CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
int fh = _open_osfhandle((long)hF, 0);
if (flags & O_TEXT)
fileflags |= FTEXT;
+ if (flags & O_NOINHERIT)
+ fileflags |= FNOINHERIT;
+
/* attempt to allocate a C Runtime file handle */
if ((fh = _alloc_osfhnd()) == -1) {
errno = EMFILE; /* too many open files */
WCHAR wNewName[MAX_PATH+1];
if (IsWin95())
- Perl_die(aTHX_ PL_no_func, "link");
+ Perl_croak(aTHX_ PL_no_func, "link");
pfnCreateHardLinkW =
(BOOL (__stdcall *)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES))
#define FTEXT 0x80 /* file handle is in text mode */
#define MAX_DESCRIPTOR_COUNT (64*32) /* this is the maximun that MSVCRT can handle */
-int __cdecl _fixed_read(int fh, void *buf, unsigned cnt)
+int __cdecl
+_fixed_read(int fh, void *buf, unsigned cnt)
{
int bytes_read; /* number of bytes read */
char *buffer; /* buffer to read to */
return -1;
}
- EnterCriticalSection(&(_pioinfo(fh)->lock)); /* lock file */
+ /*
+ * If lockinitflag is FALSE, assume fd is device
+ * lockinitflag is set to TRUE by open.
+ */
+ if (_pioinfo(fh)->lockinitflag)
+ EnterCriticalSection(&(_pioinfo(fh)->lock)); /* lock file */
bytes_read = 0; /* nothing read yet */
buffer = (char*)buf;
}
functionexit:
- LeaveCriticalSection(&(_pioinfo(fh)->lock)); /* unlock file */
+ if (_pioinfo(fh)->lockinitflag)
+ LeaveCriticalSection(&(_pioinfo(fh)->lock)); /* unlock file */
return bytes_read;
}
int ret;
void* env;
char* dir;
+ child_IO_table tbl;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
DWORD create = 0;
}
memset(&StartupInfo,0,sizeof(StartupInfo));
StartupInfo.cb = sizeof(StartupInfo);
- StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
- StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
- StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+ PerlEnv_get_child_IO(&tbl);
+ StartupInfo.hStdInput = tbl.childStdIn;
+ StartupInfo.hStdOutput = tbl.childStdOut;
+ StartupInfo.hStdError = tbl.childStdErr;
if (StartupInfo.hStdInput != INVALID_HANDLE_VALUE &&
StartupInfo.hStdOutput != INVALID_HANDLE_VALUE &&
StartupInfo.hStdError != INVALID_HANDLE_VALUE)
MALLOC_INIT;
}
+void
+win32_get_child_IO(child_IO_table* ptbl)
+{
+ ptbl->childStdIn = GetStdHandle(STD_INPUT_HANDLE);
+ ptbl->childStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ ptbl->childStdErr = GetStdHandle(STD_ERROR_HANDLE);
+}
+
+
#ifdef USE_ITHREADS
# ifdef PERL_OBJECT
}
#endif
+static void
+win32_free_argvw(pTHXo_ void *ptr)
+{
+ char** argv = (char**)ptr;
+ while(*argv) {
+ Safefree(*argv);
+ *argv++ = Nullch;
+ }
+}
+
+void
+win32_argv2utf8(pTHX_ int argc, char** argv)
+{
+ char* psz;
+ int length, wargc;
+ LPWSTR* lpwStr = CommandLineToArgvW(GetCommandLineW(), &wargc);
+ if (lpwStr && argc) {
+ while (argc--) {
+ length = WideCharToMultiByte(CP_UTF8, 0, lpwStr[--wargc], -1, NULL, 0, NULL, NULL);
+ Newz(0, psz, length, char);
+ WideCharToMultiByte(CP_UTF8, 0, lpwStr[wargc], -1, psz, length, NULL, NULL);
+ argv[argc] = psz;
+ }
+ call_atexit(win32_free_argvw, argv);
+ }
+ GlobalFree((HGLOBAL)lpwStr);
+}
+