⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_win32.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        }        strcpy(pipePath, bindPathPrefix);        strcat(pipePath, bindPath);		if (bImpersonate) {			flags |= SECURITY_SQOS_PRESENT | SECURITY_IMPERSONATION;		}        hPipe = CreateFile(pipePath,			    GENERIC_WRITE | GENERIC_READ,			    FILE_SHARE_READ | FILE_SHARE_WRITE,			    NULL,			    OPEN_EXISTING,			    flags,			    NULL);        free(pipePath);        if( hPipe == INVALID_HANDLE_VALUE || hPipe == 0)         {            return -1;        }        pseudoFd = Win32NewDescriptor(FD_PIPE_ASYNC, (int) hPipe, -1);                if (pseudoFd == -1)         {            CloseHandle(hPipe);            return -1;        }                 /*	     * Set stdin equal to our pseudo FD and create the I/O completion	     * port to be used for async I/O.	     */        if (! CreateIoCompletionPort(hPipe, hIoCompPort, pseudoFd, 1))        {	        Win32FreeDescriptor(pseudoFd);	        CloseHandle(hPipe);	        return -1;	    }    }    return pseudoFd;    }/* *-------------------------------------------------------------- * * OS_Read -- * *	Pass through to the appropriate NT read function. * * Results: *	Returns number of byes read. Mimics unix read:. *		n bytes read, 0 or -1 failure: errno contains actual error * * Side effects: *	None. * *-------------------------------------------------------------- */int OS_Read(int fd, char * buf, size_t len){    DWORD bytesRead;    int ret = -1;    ASSERT((fd >= 0) && (fd < WIN32_OPEN_MAX));    if (shutdownNow) return -1;    switch (fdTable[fd].type)     {	case FD_FILE_SYNC:	case FD_FILE_ASYNC:	case FD_PIPE_SYNC:	case FD_PIPE_ASYNC:	    if (ReadFile(fdTable[fd].fid.fileHandle, buf, len, &bytesRead, NULL))         {            ret = bytesRead;        }        else        {		    fdTable[fd].Errno = GetLastError();	    }        break;	case FD_SOCKET_SYNC:	case FD_SOCKET_ASYNC:        ret = recv(fdTable[fd].fid.sock, buf, len, 0);	    if (ret == SOCKET_ERROR)         {		    fdTable[fd].Errno = WSAGetLastError();		    ret = -1;	    }        break;            default:        ASSERT(0);    }    return ret;}/* *-------------------------------------------------------------- * * OS_Write -- * *	Perform a synchronous OS write. * * Results: *	Returns number of bytes written. Mimics unix write: *		n bytes written, 0 or -1 failure (??? couldn't find man page). * * Side effects: *	none. * *-------------------------------------------------------------- */int OS_Write(int fd, char * buf, size_t len){    DWORD bytesWritten;    int ret = -1;    ASSERT(fd >= 0 && fd < WIN32_OPEN_MAX);    if (shutdownNow) return -1;    switch (fdTable[fd].type)     {	case FD_FILE_SYNC:	case FD_FILE_ASYNC:	case FD_PIPE_SYNC:	case FD_PIPE_ASYNC:        if (WriteFile(fdTable[fd].fid.fileHandle, buf, len, &bytesWritten, NULL))         {            ret = bytesWritten;        }        else        {		    fdTable[fd].Errno = GetLastError();	    }        break;	case FD_SOCKET_SYNC:	case FD_SOCKET_ASYNC:        ret = send(fdTable[fd].fid.sock, buf, len, 0);        if (ret == SOCKET_ERROR)         {		    fdTable[fd].Errno = WSAGetLastError();		    ret = -1;	    }        break;    default:        ASSERT(0);    }    return ret;}/* *---------------------------------------------------------------------- * * OS_SpawnChild -- * *	Spawns a new server listener process, and stores the information *      relating to the child in the supplied record.  A wait handler is *	registered on the child's completion.  This involves creating *        a process on NT and preparing a command line with the required *        state (currently a -childproc flag and the server socket to use *        for accepting connections). * * Results: *      0 if success, -1 if error. * * Side effects: *      Child process spawned. * *---------------------------------------------------------------------- */int OS_SpawnChild(char *execPath, int listenFd, PROCESS_INFORMATION *pInfo, char *env){    STARTUPINFO StartupInfo;    BOOL success;    memset((void *)&StartupInfo, 0, sizeof(STARTUPINFO));    StartupInfo.cb = sizeof (STARTUPINFO);    StartupInfo.lpReserved = NULL;    StartupInfo.lpReserved2 = NULL;    StartupInfo.cbReserved2 = 0;    StartupInfo.lpDesktop = NULL;    /*     * FastCGI on NT will set the listener pipe HANDLE in the stdin of     * the new process.  The fact that there is a stdin and NULL handles     * for stdout and stderr tells the FastCGI process that this is a     * FastCGI process and not a CGI process.     */    StartupInfo.dwFlags = STARTF_USESTDHANDLES;    /*     * XXX: Do I have to dup the handle before spawning the process or is     *      it sufficient to use the handle as it's reference counted     *      by NT anyway?     */    StartupInfo.hStdInput  = fdTable[listenFd].fid.fileHandle;    StartupInfo.hStdOutput = INVALID_HANDLE_VALUE;    StartupInfo.hStdError  = INVALID_HANDLE_VALUE;    /*     * Make the listener socket inheritable.     */    success = SetHandleInformation(StartupInfo.hStdInput, HANDLE_FLAG_INHERIT,				   TRUE);    if(!success) {        //exit(99);		return -1;    }    /*     * XXX: Might want to apply some specific security attributes to the     *      processes.     */    success = CreateProcess(execPath,	/* LPCSTR address of module name */			NULL,           /* LPCSTR address of command line */		        NULL,		/* Process security attributes */			NULL,		/* Thread security attributes */			TRUE,		/* Inheritable Handes inherited. */			0,		/* DWORD creation flags  */		    env,           /* Use parent environment block */			NULL,		/* Address of current directory name */			&StartupInfo,   /* Address of STARTUPINFO  */			pInfo);	/* Address of PROCESS_INFORMATION   */    if(success) {        return 0;    } else {        return -1;    }}/* *-------------------------------------------------------------- * * OS_AsyncReadStdin -- * *	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 *      message to the StdinThread to do the synchronous read. * * Results: *	-1 if error, 0 otherwise. * * Side effects: *	Asynchronous message is queued to the StdinThread and an *      overlapped structure is allocated/initialized. * *-------------------------------------------------------------- */int OS_AsyncReadStdin(void *buf, int len, OS_AsyncProc procPtr,                      ClientData clientData){    POVERLAPPED_REQUEST pOv;    ASSERT(fdTable[STDIN_FILENO].type != FD_UNUSED);    pOv = (POVERLAPPED_REQUEST)malloc(sizeof(struct OVERLAPPED_REQUEST));    ASSERT(pOv);    memset((void *)pOv, 0, sizeof(struct OVERLAPPED_REQUEST));    pOv->clientData1 = (ClientData)buf;    pOv->instance = fdTable[STDIN_FILENO].instance;    pOv->procPtr = procPtr;    pOv->clientData = clientData;    PostQueuedCompletionStatus(hStdinCompPort, len, STDIN_FILENO,                               (LPOVERLAPPED)pOv);    return 0;}/* *-------------------------------------------------------------- * * OS_AsyncRead -- * *	This initiates an asynchronous read on the file *	handle which may be a socket or named pipe. * *	We also must save the ProcPtr and ClientData, so later *	when the io completes, we know who to call. * *	We don't look at any results here (the ReadFile may *	return data if it is cached) but do all completion *	processing in OS_Select when we get the io completion *	port done notifications.  Then we call the callback. * * Results: *	-1 if error, 0 otherwise. * * Side effects: *	Asynchronous I/O operation is queued for completion. * *-------------------------------------------------------------- */int OS_AsyncRead(int fd, int offset, void *buf, int len,		 OS_AsyncProc procPtr, ClientData clientData){    DWORD bytesRead;    POVERLAPPED_REQUEST pOv;    /*     * Catch any bogus fd values     */    ASSERT((fd >= 0) && (fd < WIN32_OPEN_MAX));    /*     * Confirm that this is an async fd     */    ASSERT(fdTable[fd].type != FD_UNUSED);    ASSERT(fdTable[fd].type != FD_FILE_SYNC);    ASSERT(fdTable[fd].type != FD_PIPE_SYNC);    ASSERT(fdTable[fd].type != FD_SOCKET_SYNC);    pOv = (POVERLAPPED_REQUEST)malloc(sizeof(struct OVERLAPPED_REQUEST));    ASSERT(pOv);    memset((void *)pOv, 0, sizeof(struct OVERLAPPED_REQUEST));    /*     * Only file offsets should be non-zero, but make sure.     */    if (fdTable[fd].type == FD_FILE_ASYNC)	if (fdTable[fd].offset >= 0)	    pOv->overlapped.Offset = fdTable[fd].offset;	else	    pOv->overlapped.Offset = offset;    pOv->instance = fdTable[fd].instance;    pOv->procPtr = procPtr;    pOv->clientData = clientData;    bytesRead = fd;    /*     * ReadFile returns: TRUE success, FALSE failure     */    if (!ReadFile(fdTable[fd].fid.fileHandle, buf, len, &bytesRead,	(LPOVERLAPPED)pOv)) {	fdTable[fd].Errno = GetLastError();	if(fdTable[fd].Errno == ERROR_NO_DATA ||	   fdTable[fd].Errno == ERROR_PIPE_NOT_CONNECTED) {	    PostQueuedCompletionStatus(hIoCompPort, 0, fd, (LPOVERLAPPED)pOv);	    return 0;	}	if(fdTable[fd].Errno != ERROR_IO_PENDING) {	    PostQueuedCompletionStatus(hIoCompPort, 0, fd, (LPOVERLAPPED)pOv);	    return -1;	}	fdTable[fd].Errno = 0;    }    return 0;}/* *-------------------------------------------------------------- * * OS_AsyncWrite -- * *	This initiates an asynchronous write on the "fake" file *	descriptor (which may be a file, socket, or named pipe). *	We also must save the ProcPtr and ClientData, so later *	when the io completes, we know who to call. * *	We don't look at any results here (the WriteFile generally *	completes immediately) but do all completion processing *	in OS_DoIo when we get the io completion port done *	notifications.  Then we call the callback. * * Results: *	-1 if error, 0 otherwise. * * Side effects: *	Asynchronous I/O operation is queued for completion. * *-------------------------------------------------------------- */int OS_AsyncWrite(int fd, int offset, void *buf, int len,		  OS_AsyncProc procPtr, ClientData clientData){    DWORD bytesWritten;    POVERLAPPED_REQUEST pOv;    /*     * Catch any bogus fd values     */    ASSERT((fd >= 0) && (fd < WIN32_OPEN_MAX));    /*     * Confirm that this is an async fd     */    ASSERT(fdTable[fd].type != FD_UNUSED);    ASSERT(fdTable[fd].type != FD_FILE_SYNC);    ASSERT(fdTable[fd].type != FD_PIPE_SYNC);    ASSERT(fdTable[fd].type != FD_SOCKET_SYNC);    pOv = (POVERLAPPED_REQUEST)malloc(sizeof(struct OVERLAPPED_REQUEST));    ASSERT(pOv);    memset((void *)pOv, 0, sizeof(struct OVERLAPPED_REQUEST));    /*     * 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	        pOv->overlapped.Offset = fdTable[fd].offset;	else	    pOv->overlapped.Offset = offset;    pOv->instance = fdTable[fd].instance;    pOv->procPtr = procPtr;    pOv->clientData = clientData;    bytesWritten = fd;    /*     * WriteFile returns: TRUE success, FALSE failure     */    if (!WriteFile(fdTable[fd].fid.fileHandle, buf, len, &bytesWritten,	(LPOVERLAPPED)pOv)) {	fdTable[fd].Errno = GetLastError();	if(fdTable[fd].Errno != ERROR_IO_PENDING) {	    PostQueuedCompletionStatus(hIoCompPort, 0, fd, (LPOVERLAPPED)pOv);	    return -1;	}	fdTable[fd].Errno = 0;    }    if (fdTable[fd].offset >= 0)	fdTable[fd].offset += len;    return 0;}/* *-------------------------------------------------------------- * * OS_Close -- * *	Closes the descriptor with routine appropriate for *      descriptor's type. * * Results: *	Socket or file is closed. Return values mimic Unix close: *		0 success, -1 failure * * Side effects: *	Entry in fdTable is marked as free. * *-------------------------------------------------------------- */int OS_Close(int fd, int shutdown_ok){    int ret = 0;    /*     * Catch it if fd is a bogus value     */    ASSERT((fd >= 0) && (fd < WIN32_OPEN_MAX));    ASSERT(fdTable[fd].type != FD_UNUSED);    switch (fdTable[fd].type) {	case FD_PIPE_SYNC:	case FD_PIPE_ASYNC:	case FD_FILE_SYNC:	case FD_FILE_ASYNC:                break;    case FD_SOCKET_SYNC:    case FD_SOCKET_ASYNC:        /*         * shutdown() the send side and then read() from client until EOF         * or a timeout expires.  This is done to minimize the potential         * that a TCP RST will be sent by our TCP stack in response to         * receipt of additional data from the client.  The RST would         * cause the client to discard potentially useful response data.         */        if (shutdown_ok)        {            if (shutdown(fdTable[fd].fid.sock, SD_SEND) == 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -