File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lighttpd / src / stream.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:35:00 2016 UTC (8 years ago) by misho
Branches: lighttpd, MAIN
CVS tags: v1_4_41p8, HEAD
lighttpd 1.4.41

    1: #include "first.h"
    2: 
    3: #include "stream.h"
    4: 
    5: #include <sys/types.h>
    6: #include <sys/stat.h>
    7: 
    8: #include <unistd.h>
    9: #include <fcntl.h>
   10: 
   11: #include "sys-mmap.h"
   12: 
   13: #ifndef O_BINARY
   14: # define O_BINARY 0
   15: #endif
   16: 
   17: /* don't want to block when open()ing a fifo */
   18: #if defined(O_NONBLOCK)
   19: # define FIFO_NONBLOCK O_NONBLOCK
   20: #else
   21: # define FIFO_NONBLOCK 0
   22: #endif
   23: 
   24: int stream_open(stream *f, const buffer *fn) {
   25: 
   26: #if !defined(__WIN32)
   27: 
   28: 	struct stat st;
   29: 	int fd;
   30: 
   31: 	f->start = NULL;
   32: 	f->size = 0;
   33: 	f->mapped = 0;
   34: 
   35: 	if (-1 == (fd = open(fn->ptr, O_RDONLY | O_BINARY | FIFO_NONBLOCK))) {
   36: 		return -1;
   37: 	}
   38: 
   39: 	if (-1 == fstat(fd, &st)) {
   40: 		close(fd);
   41: 		return -1;
   42: 	}
   43: 
   44: 	if (0 == st.st_size) {
   45: 		/* empty file doesn't need a mapping */
   46: 		close(fd);
   47: 		return 0;
   48: 	}
   49: 
   50: 	f->start = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
   51: 
   52: 	if (MAP_FAILED == f->start) {
   53: 		f->start = malloc((size_t)st.st_size);
   54: 		if (NULL == f->start
   55: 		    || st.st_size != read(fd, f->start, (size_t)st.st_size)) {
   56: 			free(f->start);
   57: 			f->start = NULL;
   58: 			close(fd);
   59: 			return -1;
   60: 		}
   61: 	} else {
   62: 		f->mapped = 1;
   63: 	}
   64: 
   65: 	close(fd);
   66: 
   67: 	f->size = st.st_size;
   68: 	return 0;
   69: 
   70: #elif defined __WIN32
   71: 
   72: 	HANDLE *fh, *mh;
   73: 	void *p;
   74: 	LARGE_INTEGER fsize;
   75: 
   76: 	f->start = NULL;
   77: 	f->size = 0;
   78: 
   79: 	fh = CreateFile(fn->ptr,
   80: 			GENERIC_READ,
   81: 			FILE_SHARE_READ,
   82: 			NULL,
   83: 			OPEN_EXISTING,
   84: 			FILE_ATTRIBUTE_READONLY,
   85: 			NULL);
   86: 
   87: 	if (!fh) return -1;
   88: 
   89: 	if (0 != GetFileSizeEx(fh, &fsize)) {
   90: 		CloseHandle(fh);
   91: 		return -1;
   92: 	}
   93: 
   94: 	if (0 == fsize) {
   95: 		CloseHandle(fh);
   96: 		return 0;
   97: 	}
   98: 
   99: 	mh = CreateFileMapping( fh,
  100: 			NULL,
  101: 			PAGE_READONLY,
  102: 			(sizeof(off_t) > 4) ? fsize >> 32 : 0,
  103: 			fsize & 0xffffffff,
  104: 			NULL);
  105: 
  106: 	if (!mh) {
  107: /*
  108: 		LPVOID lpMsgBuf;
  109: 		FormatMessage(
  110: 		        FORMAT_MESSAGE_ALLOCATE_BUFFER |
  111: 		        FORMAT_MESSAGE_FROM_SYSTEM,
  112: 		        NULL,
  113: 		        GetLastError(),
  114: 		        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  115: 		        (LPTSTR) &lpMsgBuf,
  116: 		        0, NULL );
  117: */
  118: 		CloseHandle(fh);
  119: 		return -1;
  120: 	}
  121: 
  122: 	p = MapViewOfFile(mh,
  123: 			FILE_MAP_READ,
  124: 			0,
  125: 			0,
  126: 			0);
  127: 	CloseHandle(mh);
  128: 	CloseHandle(fh);
  129: 
  130: 	f->start = p;
  131: 	f->size = (off_t)fsize;
  132: 	return 0;
  133: 
  134: #endif
  135: 
  136: }
  137: 
  138: int stream_close(stream *f) {
  139: #ifdef HAVE_MMAP
  140: 	if (f->start) {
  141: 		if (f->mapped) {
  142: 			f->mapped = 0;
  143: 			munmap(f->start, f->size);
  144: 		} else {
  145: 			free(f->start);
  146: 		}
  147: 	}
  148: #elif defined(__WIN32)
  149: 	if (f->start) UnmapViewOfFile(f->start);
  150: #endif
  151: 
  152: 	f->start = NULL;
  153: 	f->size = 0;
  154: 
  155: 	return 0;
  156: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>