*/
#ifndef lint
-static const char rcsid[] = "$Id: fcgi_stdio.c,v 1.7 1999/07/27 15:00:16 roberts Exp $";
+static const char rcsid[] = "$Id: fcgi_stdio.c,v 1.8 1999/07/28 00:24:15 roberts Exp $";
#endif /* not lint */
+#include "fcgi_config.h"
+
#ifdef _WIN32
#define DLLAPI __declspec(dllexport)
+#include <windows.h>
#endif
-#define NO_FCGI_DEFINES
-#include "fcgi_stdio.h"
-#undef NO_FCGI_DEFINES
+#include <errno.h> /* for errno */
+#include <stdarg.h> /* for va_arg */
+#include <stdlib.h> /* for malloc */
+#include <string.h> /* for strerror */
-#ifdef _WIN32
-#include <windows.h>
-#endif
-#include <errno.h>
- /* for errno */
-#include <stdarg.h>
- /* for va_arg */
-#include <stdlib.h>
- /* for malloc */
-#include <string.h>
- /* for strerror */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#define NO_FCGI_DEFINES
+#include "fcgi_stdio.h"
+#undef NO_FCGI_DEFINES
+
#include "fcgiapp.h"
#include "fcgios.h"
+#ifndef _WIN32
+
+extern char **environ;
+
+/* These definitions should be supplied by stdio.h but for some
+ * reason they get lost on certain platforms. */
+#ifndef fileno
+extern int fileno(FILE *stream);
+#endif
+
+extern FILE *fdopen(int fildes, const char *type);
+extern FILE *popen(const char *command, const char *type);
+extern int pclose(FILE *stream);
+
+#else /* _WIN32 */
+
+#define popen _popen
+
+#endif /* _WIN32 */
+
#ifndef FALSE
#define FALSE (0)
#endif
+
#ifndef TRUE
#define TRUE (1)
#endif
FCGI_FILE _fcgi_sF[3];
-#ifdef _WIN32
-#define popen _popen
-#endif
\f
/*
*----------------------------------------------------------------------
*/
static int acceptCalled = FALSE;
static int isCGI = FALSE;
-#ifndef _WIN32
-extern char **environ;
-#endif
int FCGI_Accept(void)
{
*----------------------------------------------------------------------
*/
-/*
- * These definitions should be supplied by stdio.h but for some
- * reason they get lost on certain platforms.
- */
-/*
- * XXX: Need to find the right way to handle this for NT
- */
-#ifndef _WIN32
-#ifndef fileno
-extern int fileno(FILE *stream);
-#endif
-extern FILE *fdopen(int fildes, const char *type);
-extern FILE *popen(const char *command, const char *type);
-extern int pclose(FILE *stream);
-#endif
-
int FCGI_fileno(FCGI_FILE *fp)
{
if(fp->stdio_stream)
-/*
+/*
* os_win32.c --
*
*
* All rights reserved.
*
* This file contains proprietary and confidential information and
- * remains the unpublished property of Open Market, Inc. Use,
- * disclosure, or reproduction is prohibited except as permitted by
- * express written license agreement with Open Market, Inc.
+ * remains the unpublished property of Open Market, Inc. Use,
+ * disclosure, or reproduction is prohibited except as permitted by
+ * express written license agreement with Open Market, Inc.
*
* Bill Snapper
* snapper@openmarket.com
* (Special thanks to Karen and Bill. They made my job much easier and
* significantly more enjoyable.)
*/
-#ifdef _WIN32
-#define DLLAPI __declspec(dllexport)
-#endif
-
#ifndef lint
-static const char rcsid[] = "$Id: os_win32.c,v 1.1 1997/09/16 15:36:33 stanleyg Exp $";
+static const char rcsid[] = "$Id: os_win32.c,v 1.2 1999/07/28 00:18:31 roberts Exp $";
#endif /* not lint */
-#include <windows.h>
-#include <stdio.h>
-#include "fcgios.h"
+#include "fcgi_config.h"
-/*
- * io.c will instantiate globals; all other
- * modules access these variables as externs.
- */
-#ifndef EXTRN
-#define EXTRN extern
-#endif
+#define DLLAPI __declspec(dllexport)
#include <assert.h>
+#include <stdio.h>
#include <sys/timeb.h>
+#include <windows.h>
-#define WIN32_OPEN_MAX 32 /* XXX: Small hack */
+#include "fcgios.h"
#define ASSERT assert
+#define WIN32_OPEN_MAX 32 /* XXX: Small hack */
+#define MUTEX_VARNAME "_FCGI_MUTEX_"
+
+
static HANDLE hIoCompPort = INVALID_HANDLE_VALUE;
static HANDLE hStdinCompPort = INVALID_HANDLE_VALUE;
static HANDLE hStdinThread = INVALID_HANDLE_VALUE;
static HANDLE hPipeMutex = INVALID_HANDLE_VALUE;;
static char pipeMutexEnv[80] = "";
-#define MUTEX_VARNAME "_FCGI_MUTEX_"
-
-/*
+/*
* An enumeration of the file types
* supported by the FD_TABLE structure.
*
unsigned int value;
} DESCRIPTOR;
-/*
+/*
* Structure used to map file handle and socket handle
* values into values that can be used to create unix-like
* select bitmaps, read/write for both sockets/files.
* because you can't guarantee that all applications will
* create standard input with sufficient access to perform
* asynchronous I/O. Since we don't want to block the app
- * reading from stdin we make it look like it's using I/O
+ * reading from stdin we make it look like it's using I/O
* completion ports to perform async I/O.
*
* Results:
int fd;
int bytesRead;
POVERLAPPED_REQUEST pOv;
-
+
while(doIo) {
/*
* Block until a request to read from stdin comes in or a
doIo = 0;
break;
}
-
+
ASSERT((fd == STDIN_FILENO) || (fd == -1));
if(fd == -1) {
doIo = 0;
if(ReadFile(stdioHandles[STDIN_FILENO], pOv->clientData1, bytesRead,
&bytesRead, NULL)) {
- PostQueuedCompletionStatus(hIoCompPort, bytesRead,
+ PostQueuedCompletionStatus(hIoCompPort, bytesRead,
STDIN_FILENO, (LPOVERLAPPED)pOv);
} else {
doIo = 0;
DWORD threadId;
char *cLenPtr = NULL;
char *mutexPtr = NULL;
-
+
if(libInitialized)
return 0;
if(SetNamedPipeHandleState(hListen, &pipeMode, NULL, NULL)) {
listenType = FD_PIPE_SYNC;
/*
- * Lookup the mutex. If one is found, save it and
+ * Lookup the mutex. If one is found, save it and
* remove it from the env table if it's not already
* been done.
*/
libInitialized = 1;
return 0;
}
-
+
/*
* Setup standard input asynchronous I/O. There is actually a separate
* thread spawned for this purpose. The reason for this is that some
}
}
- /*
+ /*
* Create the thread that will read stdin if the CONTENT_LENGTH
* is non-zero.
*/
int tcp = FALSE;
int flag = 1;
char *tp;
-
+
strcpy(host, bindPath);
if((tp = strchr(host, ':')) != 0) {
*tp++ = 0;
return retFd;
}
-
+
/*
* Initialize the SECURITY_ATTRIUBTES structure.
*/
localPath = malloc(bpLen+2);
strcpy(localPath, bindPathPrefix);
strcat(localPath, bindPath);
-
+
/*
* Create and setup the named pipe to be used by the fcgi server.
*/
}
return pseudoFd;
}
-
+
/*
* Not a TCP connection, create and connect to a named pipe.
*/
strcpy(pipePath, bindPathPrefix);
strcat(pipePath, bindPath);
- hPipe = CreateFile (pipePath,
+ hPipe = CreateFile (pipePath,
/* Generic access, read/write. */
GENERIC_WRITE | GENERIC_READ,
/* Share both read and write. */
}
return pseudoFd;
}
-
+
\f
/*
*--------------------------------------------------------------
StartupInfo.hStdInput = fdTable[listenFd].fid.fileHandle;
StartupInfo.hStdOutput = INVALID_HANDLE_VALUE;
StartupInfo.hStdError = INVALID_HANDLE_VALUE;
-
+
/*
* Make the listener socket inheritable.
*/
*/
success = CreateProcess(execPath, /* LPCSTR address of module name */
NULL, /* LPCSTR address of command line */
- NULL, /* Process security attributes */
+ NULL, /* Process security attributes */
NULL, /* Thread security attributes */
TRUE, /* Inheritable Handes inherited. */
0, /* DWORD creation flags */
*
* This initiates an asynchronous read on the standard
* input handle. This handle is not guaranteed to be
- * capable of performing asynchronous I/O so we send a
+ * capable of performing asynchronous I/O so we send a
* message to the StdinThread to do the synchronous read.
*
* Results:
*
*--------------------------------------------------------------
*/
-int OS_AsyncReadStdin(void *buf, int len, OS_AsyncProc procPtr,
+int OS_AsyncReadStdin(void *buf, int len, OS_AsyncProc procPtr,
ClientData clientData)
{
POVERLAPPED_REQUEST pOv;
*
*--------------------------------------------------------------
*/
-int OS_AsyncWrite(int fd, int offset, void *buf, int len,
+int OS_AsyncWrite(int fd, int offset, void *buf, int len,
OS_AsyncProc procPtr, ClientData clientData)
{
DWORD bytesWritten;
* Only file offsets should be non-zero, but make sure.
*/
if (fdTable[fd].type == FD_FILE_ASYNC)
- /*
+ /*
* Only file opened via OS_AsyncWrite with
* O_APPEND will have an offset != -1.
*/
if (fdTable[fd].offset >= 0)
- /*
+ /*
* If the descriptor has a memory mapped file
* handle, take the offsets from there.
*/
if (fdTable[fd].hMapMutex != NULL) {
/*
* Wait infinitely; this *should* not cause problems.
- */
+ */
WaitForSingleObject(fdTable[fd].hMapMutex, INFINITE);
-
+
/*
* Retrieve the shared offset values.
*/
pOv->overlapped.OffsetHigh = *(fdTable[fd].offsetHighPtr);
pOv->overlapped.Offset = *(fdTable[fd].offsetLowPtr);
-
+
/*
* Update the shared offset values for the next write
*/
*(fdTable[fd].offsetHighPtr) += 0; /* XXX How do I handle overflow */
*(fdTable[fd].offsetLowPtr) += len;
-
+
ReleaseMutex(fdTable[fd].hMapMutex);
- } else
+ } else
pOv->overlapped.Offset = fdTable[fd].offset;
else
pOv->overlapped.Offset = offset;
int ms;
int ms_last;
int err;
-
+
/* XXX
* We can loop in here, but not too long, as wait handlers
* must run.
err = WSAGetLastError();
return 0; /* timeout */
}
-
+
ASSERT((fd >= 0) && (fd < WIN32_OPEN_MAX));
/* call callback if descriptor still valid */
ASSERT(pOv);
SOCKET hSock;
int clilen = sizeof(sa);
DWORD waitForStatus;
-
+
switch(listenType) {
case FD_PIPE_SYNC:
*/
pConnected = ConnectNamedPipe(hListen, NULL) ?
TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
-
+
ReleaseMutex(hPipeMutex);
if(pConnected) {
/*
} else {
char *tp1, *tp2;
int match = 0;
- if (serverHostList == NULL)
+ if (serverHostList == NULL)
isNewConnection = TRUE;
else {
tp1 = (char *) malloc(strlen(serverHostList)+1);
while(tp1) {
if ((tp2 = strchr(tp1, ',')) != NULL)
*tp2++ = 0;
-
+
if (inet_addr(tp1) == sa.sin_addr.s_addr) {
match = 1;
break;
default:
exit(101);
break;
-
+
}
}
\f
{
long int pLong = 1L;
int err;
-
+
if(fdTable[fd].type == FD_SOCKET_SYNC && flags == O_NONBLOCK) {
if (ioctlsocket(fdTable[fd].fid.sock, FIONBIO, &pLong) ==
SOCKET_ERROR) {