From: <dan...@us...> - 2008-08-30 07:46:06
|
Revision: 1169 http://cegcc.svn.sourceforge.net/cegcc/?rev=1169&view=rev Author: dannybackx Date: 2008-08-30 07:46:02 +0000 (Sat, 30 Aug 2008) Log Message: ----------- Prevent abandoning critical section lock when calling close() on an invalid file descriptor. Modified Paths: -------------- trunk/cegcc/src/newlib/ChangeLog.cegcc trunk/cegcc/src/newlib/newlib/libc/sys/wince/io.c trunk/cegcc/src/newlib/newlib/libc/sys/wince/stat.c trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/io.h Modified: trunk/cegcc/src/newlib/ChangeLog.cegcc =================================================================== --- trunk/cegcc/src/newlib/ChangeLog.cegcc 2008-08-01 20:35:28 UTC (rev 1168) +++ trunk/cegcc/src/newlib/ChangeLog.cegcc 2008-08-30 07:46:02 UTC (rev 1169) @@ -1,3 +1,8 @@ +2008-08-29 Pawel Veselov <paw...@gm...> + * newlib/libc/sys/wince/sys/io.h newlib/libc/sys/wince/io.c + newlib/libc/sys/wince/stat.c : add critical section parameter + to FDCHECK to prevent deadlock when FDCHECK returns. + 2008-06-10 Danny Backx <dan...@us...> * newlib/libc/include/stdio.h (P_tmpdir) : Point to a directory that Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/io.c =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/io.c 2008-08-01 20:35:28 UTC (rev 1168) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/io.c 2008-08-30 07:46:02 UTC (rev 1169) @@ -1,919 +1,919 @@ -#define __USE_W32_SOCKETS - -#include <stdlib.h> -#include <stddef.h> -#include <stdio.h> -#include <sys/stat.h> -#include <string.h> -#include <fcntl.h> -#include <reent.h> -#include <errno.h> - -#include <sys/ioctl.h> -#include <sys/sysconf.h> -#include <sys/io.h> -#include <sys/fifo.h> - -#include "sys/wcetrace.h" - -#include <winsock2.h> - -void* _fifo_alloc(); - -static int fdsinitialized = 0; -static CRITICAL_SECTION critsect; - -/* mamaich: Used in hooking CreateFile/ReadFile/etc for transparent reading of RAR archives */ -typedef HANDLE pCreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); -typedef BOOL pCloseHandle(HANDLE); -typedef DWORD pSetFilePointer(HANDLE, LONG, PLONG, DWORD); -typedef BOOL pReadFile(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); -typedef BOOL pWriteFile(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED); - -extern pCreateFileW XCECreateFileW; -extern pCloseHandle XCECloseHandle; - -static pCreateFileW *_CreateFileW=XCECreateFileW; -static pCloseHandle *_CloseHandle=XCECloseHandle; -static pSetFilePointer *_SetFilePointer=SetFilePointer; -static pReadFile *_ReadFile=ReadFile; -static pWriteFile *_WriteFile=WriteFile; - -#if 1 -typedef int (* CONSOLE_READ_FUNC)(int, unsigned char *, int); -typedef int (* CONSOLE_WRITE_FUNC)(int, const unsigned char *, int); -typedef int (* CONSOLE_IOCTL_FUNC)(int, int, void *); - -HWND console_hwnd; -CONSOLE_READ_FUNC console_read_func; -CONSOLE_WRITE_FUNC console_write_func; -CONSOLE_IOCTL_FUNC console_ioctl_func; -#endif - -void SetFileFuncs(void* CF, void *SFP, void *RF, void* WF, void *CH) -{ - _CreateFileW=(pCreateFileW*)CF; - _SetFilePointer=(pSetFilePointer*)SFP; - _ReadFile=(pReadFile*)RF; - _WriteFile=(pWriteFile*)WF; - _CloseHandle=(pCloseHandle*)CH; -} - -_fdent_t _fdtab[MAXFDS]; - -/* Prototypes from local.h that probably shouldn't be here.. */ -extern int __sclose(void *); -extern _READ_WRITE_RETURN_TYPE __sread(void *, char *, int); -extern _READ_WRITE_RETURN_TYPE __swrite(void *, char const *, int); -extern fpos_t __sseek(void *, fpos_t, int); - -/* Public devops for devices we support */ -extern _DEVOPS _fifo_devops; - -int getfiletype(int fd) -{ - FDCHECK(fd); - return _fdtab[fd].type; -} - -HANDLE get_osfhandle(int fd) -{ - if(fd < 0 || fd > MAXFDS || _fdtab[fd].fd == -1) - return INVALID_HANDLE_VALUE; - return _fdtab[fd].hFile; -} - -static void -_initfds_p(int end) -{ - int i; - - InitializeCriticalSection(&critsect); - - EnterCriticalSection(&critsect); - for (i = 0; i < end; i++) - { - memset(&_fdtab[i], 0, sizeof(_fdtab[0])); - _fdtab[i].fd = -1; - } - LeaveCriticalSection(&critsect); -} - -void -_initfds() -{ - int i; - - if (fdsinitialized) - return; - fdsinitialized = 1; - - _initfds_p(MAXFDS); -} - -void -_initfds_std() -{ - /* stdin, stdio, stderr */ - _initfds_p(3); -} - -//void -//_cleanupstdio() -//{ -// fclose(stderr); -// fclose(stdout); -// fclose(stdin); -//} - -int __StdioInited = 0; - -void -_initstdio() -{ - if(!__StdioInited) - { - __StdioInited = 1; - _initstdfd(stdin, 0, (HANDLE)_fileno(_getstdfilex(0)), __SRD); - _initstdfd(stdout, 1, (HANDLE)_fileno(_getstdfilex(1)), __SWR); - _initstdfd(stderr, 2, (HANDLE)_fileno(_getstdfilex(2)), __SWR); -// atexit(_cleanupstdio); - } -} - -int -_getnewfd() -{ - int i; - - EnterCriticalSection(&critsect); - for (i = 0; i < MAXFDS; i++) { - if (_fdtab[i].fd == -1) { - _fdtab[i].flags = 0; - LeaveCriticalSection(&critsect); - return i; - } - } - LeaveCriticalSection(&critsect); - - WCETRACE(WCE_IO, "Out of file descriptors!"); - - return(-1); -} - -void -_setfd(int fd, int type, HANDLE hnd, int flags) -{ - _fdtab[fd].fd = fd; - _fdtab[fd].type = type; - _fdtab[fd].hnd = hnd; - _fdtab[fd].flags = flags; -} - -int -_assignfd(int type, HANDLE hnd, int flags) -{ - int fd; - - WCETRACE(WCE_IO, "_assignfd(%x)", hnd); - - if ((fd = _getnewfd()) >= 0) - _setfd(fd, type, hnd, flags); - - WCETRACE(WCE_IO, "_assignfd returns %d", fd); - return(fd); -} - -void -_initstdfd(FILE *fp, int fd, HANDLE hnd, int flags) -{ - if (fd < 0 || fd > 2 || fp == NULL) - return; - - _setfd(fd, IO_FILE_TYPE_CONSOLE, hnd, 0); - - WCETRACE(WCE_IO, "_initstdfd: fd %d hnd %x", fd, hnd); - - fp->_file = fd; - fp->_flags = flags; - fp->_cookie = (_PTR) fp; - fp->_read = __sread; - fp->_write = __swrite; - fp->_seek = __sseek; - fp->_close = __sclose; - -#ifdef __SCLE - if (__stextmode(fp->_file)) - fp->_flags |= __SCLE; -#endif -} - -void -_initstdfifofd(FILE *fp, int fd, int flags) -{ - if (fd < 0 || fd > 2 || fp == NULL) - return; - - _fdtab[fd].type = IO_FILE_TYPE_FIFO; - _fdtab[fd].hnd = NULL; - _fdtab[fd].flags = 0; - - WCETRACE(WCE_IO, "_initstdfifofd: fd %d fifofd %d", fd, _fdtab[fd].fd); - - fp->_file = fd; - fp->_flags = flags; - fp->_cookie = (_PTR) fp; - fp->_read = __sread; - fp->_write = __swrite; - fp->_seek = __sseek; - fp->_close = __sclose; - -#ifdef __SCLE - if (__stextmode(fp->_file)) - fp->_flags |= __SCLE; -#endif -} - -void -_initecho(int stdinfd, int stdoutfd) -{ - _FIFOIOCXT fcxt = NULL; - - WCETRACE(WCE_IO, "_initecho: stdinfd %d stdoutfd %d", stdinfd, stdoutfd); - - if (stdinfd < 0 || stdoutfd < 0) { - WCETRACE(WCE_IO, "_initecho: ERROR invalid fds (%d,%d) giving up", stdinfd, stdoutfd); - } - - fcxt = (_FIFOIOCXT) _fdtab[stdinfd].cxt; - WCETRACE(WCE_IO, "_initecho: fcxt %p", fcxt); - fflush(stdout); - - if (fcxt == NULL) { - WCETRACE(WCE_IO, "_initecho: ERROR fcxt is NULL"); - return; - } - - if (_fdtab[stdoutfd].cxt == NULL) { - WCETRACE(WCE_IO, "_initecho: ERROR stdout cxt is NULL"); - return; - } - - fcxt->echofd = stdoutfd; - fcxt->echocxt = _fdtab[stdoutfd].cxt; -} - -void * -_getiocxt(int fd) -{ - if (fd < 0 || fd > MAXFDS - 1) - return(NULL); - return(_fdtab[fd].cxt); -} - -void -_ioatexit(void) -{ - int i; - - WCETRACE(WCE_IO, "_ioatexit: STARTED"); - for (i = 0; i < MAXFDS; i++) { - if (_fdtab[i].fd != -1) { - if (_fdtab[i].type == IO_FILE_TYPE_FIFO) { - _close_r(NULL, i); - } - } - } -} - -int -_open_r(struct _reent *reent, const char *path, int flags, int mode) -{ - wchar_t wpath[MAX_PATH]; - char pathbuf[MAX_PATH]; - HANDLE hnd = NULL; - DWORD fileaccess; - DWORD fileshare; - DWORD filecreate; - DWORD fileattrib; - void *cxt; - int fd; - - WCETRACE(WCE_IO, "open(%s, %x, %o)", path, flags, mode); - - _initfds(); - - if (!strncmp("fifo", path, 4)) { - fd = _assignfd(IO_FILE_TYPE_FIFO, NULL, 0); - - if (fd < 0) { - errno = ENMFILE; - return(-1); - } - - _fdtab[fd].devops = _fifo_devops; - _fdtab[fd].cxt = cxt = _fifo_alloc(); - if ((_fdtab[fd].fd = _fdtab[fd].devops->open_r(reent, path, flags, mode, cxt)) == -1) { - WCETRACE(WCE_IO, "FIFO open fails, errno %d", errno); - _fdtab[fd].fd = -1; - return(-1); - } - } - else if(!strncmp(path, "nul", 3) || - !strncmp(path, "nul:", 4) || - !strncmp(path, "null:", 5) || - !strncmp(path, "/dev/nul", 8) || - !strncmp(path, "/dev/null", 9)) - { - fd = _assignfd(IO_FILE_TYPE_NULL, (HANDLE) -1, 0); - if (fd < 0) { - errno = ENMFILE; - return(-1); - } - _fdtab[fd].devops = NULL; - _fdtab[fd].cxt = NULL; - } else { - if (strlen(path) >= MAX_PATH) { - WCETRACE(WCE_IO, "open fails, invalid path\n"); - return(-1); - } - - fixpath(path, pathbuf); - mbstowcs(wpath, pathbuf, strlen(pathbuf) + 1); - - fileshare = FILE_SHARE_READ|FILE_SHARE_WRITE; - fileattrib = FILE_ATTRIBUTE_NORMAL; - - switch (flags & (O_RDONLY | O_WRONLY | O_RDWR)) { - case O_RDONLY: /* read access */ - fileaccess = GENERIC_READ; - break; - case O_WRONLY: /* write access */ - fileaccess = GENERIC_WRITE; - break; - case O_RDWR: /* read and write access */ - fileaccess = GENERIC_READ | GENERIC_WRITE; - break; - default: /* error, bad flags */ - errno = EINVAL; - return -1; - } - - switch (flags & (O_CREAT | O_EXCL | O_TRUNC)) { - case 0: - case O_EXCL: /* ignore EXCL w/o CREAT */ - filecreate = OPEN_EXISTING; - break; - case O_CREAT: - filecreate = OPEN_ALWAYS; - break; - case O_CREAT | O_EXCL: - case O_CREAT | O_TRUNC | O_EXCL: - filecreate = CREATE_NEW; - break; - - case O_TRUNC: - case O_TRUNC | O_EXCL: /* ignore EXCL w/o CREAT */ - filecreate = TRUNCATE_EXISTING; - break; - case O_CREAT | O_TRUNC: - filecreate = CREATE_ALWAYS; - break; - default: - /* this can't happen ... all cases are covered */ - errno = EINVAL; - return(-1); - } - - if ((hnd = _CreateFileW(wpath, fileaccess, fileshare, NULL, filecreate, - fileattrib, NULL)) == INVALID_HANDLE_VALUE) { - errno = _winerr2errno(GetLastError()); - WCETRACE(WCE_IO, "_CreateFile(%s): errno=%d oserr=%d\n", pathbuf, errno, GetLastError()); - return(-1); - } - - fd = _assignfd(IO_FILE_TYPE_FILE, hnd, 0); - - if (fd < 0) { - errno = ENMFILE; - return(-1); - } - _fdtab[fd].devops = NULL; - _fdtab[fd].cxt = NULL; - - if (flags & O_APPEND) { - _SetFilePointer(hnd, 0, NULL, FILE_END); - } - } - - WCETRACE(WCE_IO, "open returns %d fd %d cxt %p (hnd %x)", fd, _fdtab[fd].fd, cxt, hnd); - return fd; -} - -int -_close_r(struct _reent *reent, int fd) -{ - WCETRACE(WCE_IO, "close(%d)", fd); - WCETRACE(WCE_IO, "close: fd %d type %d flags %x hnd %p cxt %p", _fdtab[fd].fd, - _fdtab[fd].type, _fdtab[fd].flags, _fdtab[fd].hnd, _fdtab[fd].cxt); - - EnterCriticalSection(&critsect); - FDCHECK(fd); - - if (_fdtab[fd].devops == NULL) { - if (_fdtab[fd].type == IO_FILE_TYPE_FILE) { - _CloseHandle(_fdtab[fd].hnd); - } else if (_fdtab[fd].type == IO_FILE_TYPE_SOCKET) { - closesocket(fd); - } else if(_fdtab[fd].type == IO_FILE_TYPE_NULL) { - } - } else { - WCETRACE(WCE_IO, "close: doing device-specific close for fd %d", _fdtab[fd].fd); - _fdtab[fd].devops->close_r(reent, _fdtab[fd].fd, _fdtab[fd].cxt); - if (_fdtab[fd].cxt != NULL) { - free(_fdtab[fd].cxt); - _fdtab[fd].cxt = NULL; - } - } - - /* IMPORTANT - reset fd fields here */ - memset(&_fdtab[fd], 0, sizeof(_fdent_t)); - _fdtab[fd].fd = -1; - LeaveCriticalSection(&critsect); - - return(0); -} - -_ssize_t -_read_r(struct _reent *reent, int fd, void *buf, size_t count) -{ - int nread; - int error; - - WCETRACE(WCE_IO, "read(fd = %d, count = %d, hnd %x)", fd, count, _fdtab[fd].hnd); - - if ((!__StdioInited) && (fd >= 0) && (fd <= 2)) - { - WCETRACE(WCE_IO, "read from fd = %d with stdio uninitialized", fd); - return count; - } - - FDCHECK(fd); - - if (_fdtab[fd].devops == NULL) { - if (_fdtab[fd].type == IO_FILE_TYPE_FILE || _fdtab[fd].type == IO_FILE_TYPE_CONSOLE) { - if (_ReadFile(_fdtab[fd].hnd, buf, count, (DWORD *)&nread, NULL) == FALSE) { - WCETRACE(WCE_IO, "_ReadFile: %d", GetLastError()); - errno = EIO; - return(-1); - } - } else if (_fdtab[fd].type == IO_FILE_TYPE_SOCKET) { - if ((nread = recv(fd, buf, count, 0)) == SOCKET_ERROR) { - /* error = WSAGetLastError(); */ - error = 1; - WCETRACE(WCE_IO, "read: recv failed %d\n", error); - if (error == WSAEWOULDBLOCK) { - errno = EAGAIN; - return(-1); - } - - errno = _winerr2errno(error); - return(-1); - } - } else if (_fdtab[fd].type == IO_FILE_TYPE_NULL) { - WCETRACE(WCE_IO, "warning - read called w/IO_FILE_TYPE_NULL"); - nread = 0; - } - } else { - nread = _fdtab[fd].devops->read_r(reent, _fdtab[fd].fd, buf, count, _fdtab[fd].cxt); - } - - return(nread); -} - -_ssize_t -_write_r(struct _reent *reent, int fd, const void *buf, size_t count){ - int nwritten = 0; - int werr; - - WCETRACE(WCE_IO, "write(%d, %d, %x)", fd, count, _fdtab[fd].hnd); - EnterCriticalSection(&critsect); - -#if 1 - if (fd == 2 || fd == 1) - { - const char* out = fd == 2?"stderr: ":"stdout: "; - WCETRACE(WCE_IO, "%s : %s", out, buf); - } -#endif - - /* until we can call console stuff inside the PE loader */ - if ((!__StdioInited) && (fd >= 0) && (fd <= 2)) - { - WCETRACE(WCE_IO, "write to fd = %d with stdio uninitialized", fd); - LeaveCriticalSection(&critsect); - return count; - } - - if (_fdtab[fd].devops == NULL) { - if (_fdtab[fd].type == IO_FILE_TYPE_FILE || _fdtab[fd].type == IO_FILE_TYPE_CONSOLE) { - if (_WriteFile(_fdtab[fd].hnd, buf, count, (DWORD *)&nwritten, NULL) == FALSE) { - if ((fd == 1 || fd == 2) && (_fdtab[fd].hnd == (HANDLE)-1)) - { - /* ignore writting errors to stdout and stderr. happens when we don't have a console installed */ - /* ### TODO replace this with something better */ - nwritten = count; - } - else - { - WCETRACE(WCE_IO, "_WriteFile: hnd %x error %d\n", _fdtab[fd].hnd, GetLastError()); - errno = EIO; - LeaveCriticalSection(&critsect); - return(-1); - } - } - } else if (_fdtab[fd].type == IO_FILE_TYPE_SOCKET) { - if ((nwritten = (int)send(fd, buf, count, 0)) == SOCKET_ERROR) { - /* werr = WSAGetLastError(); */ - werr = 1; - WCETRACE(WCE_IO, "send: sock %d error %d", _fdtab[fd].hnd, werr); - errno = _winerr2errno(werr); - LeaveCriticalSection(&critsect); - return(-1); - } - } else if (_fdtab[fd].type == IO_FILE_TYPE_NULL) { - // pretty normal, no? -// WCETRACE(WCE_IO, "warning - write called w/IO_FILE_TYPE_NULL"); - nwritten = count; - } - } else { - nwritten = _fdtab[fd].devops->write_r(reent, _fdtab[fd].fd, buf, count, _fdtab[fd].cxt); - } - - LeaveCriticalSection(&critsect); - return nwritten; -} - -off_t -_lseek_r(struct _reent *reent, int fd, off_t offset, int whence) { - off_t newpos; - int method; - WCETRACE(WCE_IO, "lseek(%d, %d, %d)", fd, offset, whence); - - FDCHECK(fd); - - if (_fdtab[fd].devops == NULL) { - switch (whence) { - case SEEK_SET: - method = FILE_BEGIN; - break; - case SEEK_CUR: - method = FILE_CURRENT; - break; - case SEEK_END: - method = FILE_END; - break; - default: - method = FILE_BEGIN; - } - - if (_fdtab[fd].type == IO_FILE_TYPE_FILE) { - if ((newpos = _SetFilePointer(_fdtab[fd].hnd, (LONG)offset, NULL, (DWORD)method)) == -1) { - WCETRACE(WCE_IO, "_SetFilePointer(%x): error %d", _fdtab[fd].hnd, GetLastError()); - errno = EIO; - newpos = -1; - } - } else { - errno = EINVAL; - newpos = -1; - } - } else { - newpos = _fdtab[fd].devops->lseek_r(reent, _fdtab[fd].fd, offset, whence, _fdtab[fd].cxt); - } - - WCETRACE(WCE_IO, "lseek returns %d", newpos); - return(newpos); -} - -BOOL XCECopyFileW( - LPCWSTR lpExistingFileName, - LPCWSTR lpNewFileName, - BOOL bFailIfExists -); - -int -_link_r(struct _reent *reent, const char *old, const char *new) -{ - wchar_t wpathOld[MAX_PATH]; - wchar_t wpathNew[MAX_PATH]; - char pathOld[MAX_PATH]; - char pathNew[MAX_PATH]; - fixpath(old, pathOld); - fixpath(new, pathNew); - mbstowcs(wpathOld, pathOld, MAX_PATH); - mbstowcs(wpathNew, pathNew, MAX_PATH); - if(0==XCECopyFileW(wpathOld,wpathNew,FALSE)) - { -// printf("failed rename '%s' to '%s'\n",pathOld,pathNew); - errno = _winerr2errno(GetLastError()); - return(-1); - } - return 0; -} - -int -_unlink_r(struct _reent *reent, const char *path) -{ - wchar_t pathw[MAX_PATH]; - char pathbuf[MAX_PATH]; - BOOL res; - - if (path == NULL) - return(-1); - - fixpath(path, pathbuf); - mbstowcs(pathw, pathbuf, MAX_PATH); - res = DeleteFileW(pathw); - - if (res == FALSE) { - errno = _winerr2errno(GetLastError()); - return(-1); - } - - return(0); -} - -static int -_fd_to_socket(struct fd_set *set, int *hndmap) -{ - int i; - - if (set == NULL) - return(0); - - for (i = 0; i < set->fd_count; i++) { - int fd = (int)set->fd_array[i]; - FDCHECK(fd); - - /* On WINCE, only IO_FILE_TYPE_SOCKET is handled */ - if (_fdtab[fd].type == IO_FILE_TYPE_SOCKET) { - SOCKET s = _fdtab[fd].sock; - hndmap[fd] = s; - WCETRACE(WCE_IO, "_fd_to_socket: fd = %d, handle = %d", fd, s); - set->fd_array[i] = s; - } else { - WCETRACE(WCE_IO, "_fd_to_socket: fd = %d is not a socket", fd); - } - } - return(0); -} - -static void -_socket_to_fd(fd_set *set, int *hndmap) -{ - int i, j, fd; - - if (set == NULL) - return; - - if (set->fd_count > MAXFDS) { - WCETRACE(WCE_IO, "select (_socket_to_fd) ERROR fd_count > MAXFDS (%d > %d)", - set->fd_count, MAXFDS); - } - - for (i = 0; i < set->fd_count; i++) { - fd = -1; - /* Hunt for matching hnd in the hndmap */ - for (j = 0; j < MAXFDS; j++) { - if (hndmap[j] == set->fd_array[i]) { - fd = j; - break; - } - } - - if (fd < 0 || fd > MAXFDS) { - WCETRACE(WCE_IO, "_socket_to_fd: ERROR weird fd %d", fd); - } else { - set->fd_array[i] = fd; - } - } -} - -#if 0 -int -select(int n, fd_set *rfds, fd_set* wfds, fd_set* xfds, struct timeval *timeout) -{ - int i; - int status; - fd_set r, w, x; - int werr, hndmap[MAXFDS]; - SOCKET s; - - WCETRACE(WCE_IO, "select(%d, %p, %p, %p, %p)", n, rfds, wfds, xfds, timeout); - if (timeout != NULL) { - WCETRACE(WCE_IO, "select: timeout {%d,%d}", timeout->tv_sec, timeout->tv_usec); - } - - /* Initialze hndmap - this is the SOCKET->fd mapping for use later */ - for (i = 0; i < MAXFDS; i++) - hndmap[i] = -1; - - if (rfds != NULL) { - if (_fd_to_socket(rfds, hndmap) < 0) { - WCETRACE(WCE_IO, "select: bad rfds"); - return(-1); - } - } - - if (wfds != NULL) { - if (_fd_to_socket(wfds, hndmap) < 0) { - WCETRACE(WCE_IO, "select: bad wfds"); - return(-1); - } - } - - if (xfds != NULL) { - if (_fd_to_socket(xfds, hndmap) < 0) { - WCETRACE(WCE_IO, "select: bad xfds"); - return(-1); - } - } - - status = __MS_select(n, rfds, wfds, xfds, timeout); - WCETRACE(WCE_IO, "select: returns %d errno %d", status, errno); - - /* Give up here if there is an select error */ - if (status == SOCKET_ERROR) { - int werr = XCEWSAGetLastError(); - errno = _winerr2errno(werr); - return(-1); - } - - /* Finally we must translate socket descriptors back to fds */ - if (rfds != NULL) - _socket_to_fd(rfds, hndmap); - - if (wfds != NULL) - _socket_to_fd(wfds, hndmap); - - if (xfds != NULL) - _socket_to_fd(xfds, hndmap); - - return(status); -} -#endif - -int -ioctl(int fd, unsigned int request, void *arg) -{ - DWORD high, low; - int length, pos, avail, *iptr; - int werr; - SOCKET s; - - WCETRACE(WCE_IO, "ioctl(%d, %p %p)", fd, request, arg); - - FDCHECK(fd); - - if (_fdtab[fd].devops == NULL) { - if (_fdtab[fd].type == IO_FILE_TYPE_FILE) { - switch (request) { - case FIONREAD: - if (arg == NULL) { - errno = EINVAL; - return(-1); - } - low = GetFileSize(_fdtab[fd].hnd, &high); - - /* FIXME: Error checking */ - length = (int)(((long long)high) << 32L) | (long long)low; - WCETRACE(WCE_IO, "ioctl(%d (FIONREAD) length %d", fd, length); - - low = _SetFilePointer(_fdtab[fd].hnd, 0, (PLONG)&high, FILE_CURRENT); - if ((low == 0xffffffff) && (GetLastError() != NO_ERROR)) { - errno = EBADF; - return(-1); - } - - pos = (int)(((long long)high) << 32L) | (long long)low; - avail = length - pos; - WCETRACE(WCE_IO, "ioctl(%d (FIONREAD) pos %d avail %d", fd, pos, avail); - iptr = (int *)arg; - *iptr = (avail > 0) ? avail : 0; - return(0); - default: - errno = ENOSYS; - return(-1); - } - } else if (_fdtab[fd].type == IO_FILE_TYPE_SOCKET) { - s = _fdtab[fd].sock; - WCETRACE(WCE_IO, "ioctl: doing ioctlsocket w/0x%x (fd %d hnd %x)", request, fd, s); - if (ioctlsocket(fd, request, arg) == SOCKET_ERROR) { - /* werr = WSAGetLastError(); */ - werr = 1; - errno = _winerr2errno(werr); - return(-1); - } - } else if(_fdtab[fd].type == IO_FILE_TYPE_NULL) { - errno = ENOSYS; - return(-1); - } - } else { - return(_fdtab[fd].devops->ioctl_r(NULL, _fdtab[fd].fd, request, _fdtab[fd].cxt, arg)); - } - - return(0); -} - -int -_getpid_r(struct _reent *reent) -{ - int pid; - - pid = GetCurrentProcessId(); -// return pid & 0x7FFFFFFF; // pedro: Reiner, what is the rationale for this in celib? - return pid; -} - -int -isatty(int fd) -{ - WCETRACE(WCE_IO, "isatty(%d)", fd); - - if (!fdsinitialized) - return(FALSE); - - if (_fdtab[fd].type == IO_FILE_TYPE_CONSOLE || - _fdtab[fd].type == IO_FILE_TYPE_FIFO) { - WCETRACE(WCE_IO, "isatty(%d): yes", fd); - return(TRUE); - } - - WCETRACE(WCE_IO, "isatty(%d): no", fd); - return(FALSE); -} - -int -ftruncate(int fd, off_t size) -{ - DWORD newpos; - - FDCHECK(fd); - - if (_fdtab[fd].type != IO_FILE_TYPE_FILE) { - errno = EBADF; - return -1; - } - - if ((newpos = _SetFilePointer(_fdtab[fd].hnd, size, NULL, - FILE_BEGIN)) == -1) - { - errno = _winerr2errno(GetLastError()); - return -1; - } - - if(!SetEndOfFile(_fdtab[fd].hnd)) - { - errno = _winerr2errno(GetLastError()); - return -1; - } - - return 0; -} - -// TODO: The fd entry is simply copied. When one of the files -// is closed, the handle is also closed! There should be a -// refcount on the handles! That would require another table. - -// TODO: Consider using DuplicateHandle here. - -int -dup(int fd) -{ - int newfd; - - - newfd = _getnewfd(); - - if(newfd >= 0) - memcpy(&_fdtab[newfd], &_fdtab[fd], sizeof(_fdent_t)); - - return newfd; -} - -int -dup2(int fd1, int fd2) -{ - if(fd2 < 0 || fd2 >= MAXFDS); - { - errno = EBADF; - return -1; - } - - if(_fdtab[fd2].fd != -1) - close(fd2); - - memcpy(&_fdtab[fd2], &_fdtab[fd1], sizeof(_fdent_t)); - - return fd2; -} +#define __USE_W32_SOCKETS + +#include <stdlib.h> +#include <stddef.h> +#include <stdio.h> +#include <sys/stat.h> +#include <string.h> +#include <fcntl.h> +#include <reent.h> +#include <errno.h> + +#include <sys/ioctl.h> +#include <sys/sysconf.h> +#include <sys/io.h> +#include <sys/fifo.h> + +#include "sys/wcetrace.h" + +#include <winsock2.h> + +void* _fifo_alloc(); + +static int fdsinitialized = 0; +static CRITICAL_SECTION critsect; + +/* mamaich: Used in hooking CreateFile/ReadFile/etc for transparent reading of RAR archives */ +typedef HANDLE pCreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); +typedef BOOL pCloseHandle(HANDLE); +typedef DWORD pSetFilePointer(HANDLE, LONG, PLONG, DWORD); +typedef BOOL pReadFile(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); +typedef BOOL pWriteFile(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED); + +extern pCreateFileW XCECreateFileW; +extern pCloseHandle XCECloseHandle; + +static pCreateFileW *_CreateFileW=XCECreateFileW; +static pCloseHandle *_CloseHandle=XCECloseHandle; +static pSetFilePointer *_SetFilePointer=SetFilePointer; +static pReadFile *_ReadFile=ReadFile; +static pWriteFile *_WriteFile=WriteFile; + +#if 1 +typedef int (* CONSOLE_READ_FUNC)(int, unsigned char *, int); +typedef int (* CONSOLE_WRITE_FUNC)(int, const unsigned char *, int); +typedef int (* CONSOLE_IOCTL_FUNC)(int, int, void *); + +HWND console_hwnd; +CONSOLE_READ_FUNC console_read_func; +CONSOLE_WRITE_FUNC console_write_func; +CONSOLE_IOCTL_FUNC console_ioctl_func; +#endif + +void SetFileFuncs(void* CF, void *SFP, void *RF, void* WF, void *CH) +{ + _CreateFileW=(pCreateFileW*)CF; + _SetFilePointer=(pSetFilePointer*)SFP; + _ReadFile=(pReadFile*)RF; + _WriteFile=(pWriteFile*)WF; + _CloseHandle=(pCloseHandle*)CH; +} + +_fdent_t _fdtab[MAXFDS]; + +/* Prototypes from local.h that probably shouldn't be here.. */ +extern int __sclose(void *); +extern _READ_WRITE_RETURN_TYPE __sread(void *, char *, int); +extern _READ_WRITE_RETURN_TYPE __swrite(void *, char const *, int); +extern fpos_t __sseek(void *, fpos_t, int); + +/* Public devops for devices we support */ +extern _DEVOPS _fifo_devops; + +int getfiletype(int fd) +{ + FDCHECK(fd, 0); + return _fdtab[fd].type; +} + +HANDLE get_osfhandle(int fd) +{ + if(fd < 0 || fd > MAXFDS || _fdtab[fd].fd == -1) + return INVALID_HANDLE_VALUE; + return _fdtab[fd].hFile; +} + +static void +_initfds_p(int end) +{ + int i; + + InitializeCriticalSection(&critsect); + + EnterCriticalSection(&critsect); + for (i = 0; i < end; i++) + { + memset(&_fdtab[i], 0, sizeof(_fdtab[0])); + _fdtab[i].fd = -1; + } + LeaveCriticalSection(&critsect); +} + +void +_initfds() +{ + int i; + + if (fdsinitialized) + return; + fdsinitialized = 1; + + _initfds_p(MAXFDS); +} + +void +_initfds_std() +{ + /* stdin, stdio, stderr */ + _initfds_p(3); +} + +//void +//_cleanupstdio() +//{ +// fclose(stderr); +// fclose(stdout); +// fclose(stdin); +//} + +int __StdioInited = 0; + +void +_initstdio() +{ + if(!__StdioInited) + { + __StdioInited = 1; + _initstdfd(stdin, 0, (HANDLE)_fileno(_getstdfilex(0)), __SRD); + _initstdfd(stdout, 1, (HANDLE)_fileno(_getstdfilex(1)), __SWR); + _initstdfd(stderr, 2, (HANDLE)_fileno(_getstdfilex(2)), __SWR); +// atexit(_cleanupstdio); + } +} + +int +_getnewfd() +{ + int i; + + EnterCriticalSection(&critsect); + for (i = 0; i < MAXFDS; i++) { + if (_fdtab[i].fd == -1) { + _fdtab[i].flags = 0; + LeaveCriticalSection(&critsect); + return i; + } + } + LeaveCriticalSection(&critsect); + + WCETRACE(WCE_IO, "Out of file descriptors!"); + + return(-1); +} + +void +_setfd(int fd, int type, HANDLE hnd, int flags) +{ + _fdtab[fd].fd = fd; + _fdtab[fd].type = type; + _fdtab[fd].hnd = hnd; + _fdtab[fd].flags = flags; +} + +int +_assignfd(int type, HANDLE hnd, int flags) +{ + int fd; + + WCETRACE(WCE_IO, "_assignfd(%x)", hnd); + + if ((fd = _getnewfd()) >= 0) + _setfd(fd, type, hnd, flags); + + WCETRACE(WCE_IO, "_assignfd returns %d", fd); + return(fd); +} + +void +_initstdfd(FILE *fp, int fd, HANDLE hnd, int flags) +{ + if (fd < 0 || fd > 2 || fp == NULL) + return; + + _setfd(fd, IO_FILE_TYPE_CONSOLE, hnd, 0); + + WCETRACE(WCE_IO, "_initstdfd: fd %d hnd %x", fd, hnd); + + fp->_file = fd; + fp->_flags = flags; + fp->_cookie = (_PTR) fp; + fp->_read = __sread; + fp->_write = __swrite; + fp->_seek = __sseek; + fp->_close = __sclose; + +#ifdef __SCLE + if (__stextmode(fp->_file)) + fp->_flags |= __SCLE; +#endif +} + +void +_initstdfifofd(FILE *fp, int fd, int flags) +{ + if (fd < 0 || fd > 2 || fp == NULL) + return; + + _fdtab[fd].type = IO_FILE_TYPE_FIFO; + _fdtab[fd].hnd = NULL; + _fdtab[fd].flags = 0; + + WCETRACE(WCE_IO, "_initstdfifofd: fd %d fifofd %d", fd, _fdtab[fd].fd); + + fp->_file = fd; + fp->_flags = flags; + fp->_cookie = (_PTR) fp; + fp->_read = __sread; + fp->_write = __swrite; + fp->_seek = __sseek; + fp->_close = __sclose; + +#ifdef __SCLE + if (__stextmode(fp->_file)) + fp->_flags |= __SCLE; +#endif +} + +void +_initecho(int stdinfd, int stdoutfd) +{ + _FIFOIOCXT fcxt = NULL; + + WCETRACE(WCE_IO, "_initecho: stdinfd %d stdoutfd %d", stdinfd, stdoutfd); + + if (stdinfd < 0 || stdoutfd < 0) { + WCETRACE(WCE_IO, "_initecho: ERROR invalid fds (%d,%d) giving up", stdinfd, stdoutfd); + } + + fcxt = (_FIFOIOCXT) _fdtab[stdinfd].cxt; + WCETRACE(WCE_IO, "_initecho: fcxt %p", fcxt); + fflush(stdout); + + if (fcxt == NULL) { + WCETRACE(WCE_IO, "_initecho: ERROR fcxt is NULL"); + return; + } + + if (_fdtab[stdoutfd].cxt == NULL) { + WCETRACE(WCE_IO, "_initecho: ERROR stdout cxt is NULL"); + return; + } + + fcxt->echofd = stdoutfd; + fcxt->echocxt = _fdtab[stdoutfd].cxt; +} + +void * +_getiocxt(int fd) +{ + if (fd < 0 || fd > MAXFDS - 1) + return(NULL); + return(_fdtab[fd].cxt); +} + +void +_ioatexit(void) +{ + int i; + + WCETRACE(WCE_IO, "_ioatexit: STARTED"); + for (i = 0; i < MAXFDS; i++) { + if (_fdtab[i].fd != -1) { + if (_fdtab[i].type == IO_FILE_TYPE_FIFO) { + _close_r(NULL, i); + } + } + } +} + +int +_open_r(struct _reent *reent, const char *path, int flags, int mode) +{ + wchar_t wpath[MAX_PATH]; + char pathbuf[MAX_PATH]; + HANDLE hnd = NULL; + DWORD fileaccess; + DWORD fileshare; + DWORD filecreate; + DWORD fileattrib; + void *cxt; + int fd; + + WCETRACE(WCE_IO, "open(%s, %x, %o)", path, flags, mode); + + _initfds(); + + if (!strncmp("fifo", path, 4)) { + fd = _assignfd(IO_FILE_TYPE_FIFO, NULL, 0); + + if (fd < 0) { + errno = ENMFILE; + return(-1); + } + + _fdtab[fd].devops = _fifo_devops; + _fdtab[fd].cxt = cxt = _fifo_alloc(); + if ((_fdtab[fd].fd = _fdtab[fd].devops->open_r(reent, path, flags, mode, cxt)) == -1) { + WCETRACE(WCE_IO, "FIFO open fails, errno %d", errno); + _fdtab[fd].fd = -1; + return(-1); + } + } + else if(!strncmp(path, "nul", 3) || + !strncmp(path, "nul:", 4) || + !strncmp(path, "null:", 5) || + !strncmp(path, "/dev/nul", 8) || + !strncmp(path, "/dev/null", 9)) + { + fd = _assignfd(IO_FILE_TYPE_NULL, (HANDLE) -1, 0); + if (fd < 0) { + errno = ENMFILE; + return(-1); + } + _fdtab[fd].devops = NULL; + _fdtab[fd].cxt = NULL; + } else { + if (strlen(path) >= MAX_PATH) { + WCETRACE(WCE_IO, "open fails, invalid path\n"); + return(-1); + } + + fixpath(path, pathbuf); + mbstowcs(wpath, pathbuf, strlen(pathbuf) + 1); + + fileshare = FILE_SHARE_READ|FILE_SHARE_WRITE; + fileattrib = FILE_ATTRIBUTE_NORMAL; + + switch (flags & (O_RDONLY | O_WRONLY | O_RDWR)) { + case O_RDONLY: /* read access */ + fileaccess = GENERIC_READ; + break; + case O_WRONLY: /* write access */ + fileaccess = GENERIC_WRITE; + break; + case O_RDWR: /* read and write access */ + fileaccess = GENERIC_READ | GENERIC_WRITE; + break; + default: /* error, bad flags */ + errno = EINVAL; + return -1; + } + + switch (flags & (O_CREAT | O_EXCL | O_TRUNC)) { + case 0: + case O_EXCL: /* ignore EXCL w/o CREAT */ + filecreate = OPEN_EXISTING; + break; + case O_CREAT: + filecreate = OPEN_ALWAYS; + break; + case O_CREAT | O_EXCL: + case O_CREAT | O_TRUNC | O_EXCL: + filecreate = CREATE_NEW; + break; + + case O_TRUNC: + case O_TRUNC | O_EXCL: /* ignore EXCL w/o CREAT */ + filecreate = TRUNCATE_EXISTING; + break; + case O_CREAT | O_TRUNC: + filecreate = CREATE_ALWAYS; + break; + default: + /* this can't happen ... all cases are covered */ + errno = EINVAL; + return(-1); + } + + if ((hnd = _CreateFileW(wpath, fileaccess, fileshare, NULL, filecreate, + fileattrib, NULL)) == INVALID_HANDLE_VALUE) { + errno = _winerr2errno(GetLastError()); + WCETRACE(WCE_IO, "_CreateFile(%s): errno=%d oserr=%d\n", pathbuf, errno, GetLastError()); + return(-1); + } + + fd = _assignfd(IO_FILE_TYPE_FILE, hnd, 0); + + if (fd < 0) { + errno = ENMFILE; + return(-1); + } + _fdtab[fd].devops = NULL; + _fdtab[fd].cxt = NULL; + + if (flags & O_APPEND) { + _SetFilePointer(hnd, 0, NULL, FILE_END); + } + } + + WCETRACE(WCE_IO, "open returns %d fd %d cxt %p (hnd %x)", fd, _fdtab[fd].fd, cxt, hnd); + return fd; +} + +int +_close_r(struct _reent *reent, int fd) +{ + WCETRACE(WCE_IO, "close(%d)", fd); + WCETRACE(WCE_IO, "close: fd %d type %d flags %x hnd %p cxt %p", _fdtab[fd].fd, + _fdtab[fd].type, _fdtab[fd].flags, _fdtab[fd].hnd, _fdtab[fd].cxt); + + EnterCriticalSection(&critsect); + FDCHECK(fd, &critsect); + + if (_fdtab[fd].devops == NULL) { + if (_fdtab[fd].type == IO_FILE_TYPE_FILE) { + _CloseHandle(_fdtab[fd].hnd); + } else if (_fdtab[fd].type == IO_FILE_TYPE_SOCKET) { + closesocket(fd); + } else if(_fdtab[fd].type == IO_FILE_TYPE_NULL) { + } + } else { + WCETRACE(WCE_IO, "close: doing device-specific close for fd %d", _fdtab[fd].fd); + _fdtab[fd].devops->close_r(reent, _fdtab[fd].fd, _fdtab[fd].cxt); + if (_fdtab[fd].cxt != NULL) { + free(_fdtab[fd].cxt); + _fdtab[fd].cxt = NULL; + } + } + + /* IMPORTANT - reset fd fields here */ + memset(&_fdtab[fd], 0, sizeof(_fdent_t)); + _fdtab[fd].fd = -1; + LeaveCriticalSection(&critsect); + + return(0); +} + +_ssize_t +_read_r(struct _reent *reent, int fd, void *buf, size_t count) +{ + int nread; + int error; + + WCETRACE(WCE_IO, "read(fd = %d, count = %d, hnd %x)", fd, count, _fdtab[fd].hnd); + + if ((!__StdioInited) && (fd >= 0) && (fd <= 2)) + { + WCETRACE(WCE_IO, "read from fd = %d with stdio uninitialized", fd); + return count; + } + + FDCHECK(fd, 0); + + if (_fdtab[fd].devops == NULL) { + if (_fdtab[fd].type == IO_FILE_TYPE_FILE || _fdtab[fd].type == IO_FILE_TYPE_CONSOLE) { + if (_ReadFile(_fdtab[fd].hnd, buf, count, (DWORD *)&nread, NULL) == FALSE) { + WCETRACE(WCE_IO, "_ReadFile: %d", GetLastError()); + errno = EIO; + return(-1); + } + } else if (_fdtab[fd].type == IO_FILE_TYPE_SOCKET) { + if ((nread = recv(fd, buf, count, 0)) == SOCKET_ERROR) { + /* error = WSAGetLastError(); */ + error = 1; + WCETRACE(WCE_IO, "read: recv failed %d\n", error); + if (error == WSAEWOULDBLOCK) { + errno = EAGAIN; + return(-1); + } + + errno = _winerr2errno(error); + return(-1); + } + } else if (_fdtab[fd].type == IO_FILE_TYPE_NULL) { + WCETRACE(WCE_IO, "warning - read called w/IO_FILE_TYPE_NULL"); + nread = 0; + } + } else { + nread = _fdtab[fd].devops->read_r(reent, _fdtab[fd].fd, buf, count, _fdtab[fd].cxt); + } + + return(nread); +} + +_ssize_t +_write_r(struct _reent *reent, int fd, const void *buf, size_t count){ + int nwritten = 0; + int werr; + + WCETRACE(WCE_IO, "write(%d, %d, %x)", fd, count, _fdtab[fd].hnd); + EnterCriticalSection(&critsect); + +#if 1 + if (fd == 2 || fd == 1) + { + const char* out = fd == 2?"stderr: ":"stdout: "; + WCETRACE(WCE_IO, "%s : %s", out, buf); + } +#endif + + /* until we can call console stuff inside the PE loader */ + if ((!__StdioInited) && (fd >= 0) && (fd <= 2)) + { + WCETRACE(WCE_IO, "write to fd = %d with stdio uninitialized", fd); + LeaveCriticalSection(&critsect); + return count; + } + + if (_fdtab[fd].devops == NULL) { + if (_fdtab[fd].type == IO_FILE_TYPE_FILE || _fdtab[fd].type == IO_FILE_TYPE_CONSOLE) { + if (_WriteFile(_fdtab[fd].hnd, buf, count, (DWORD *)&nwritten, NULL) == FALSE) { + if ((fd == 1 || fd == 2) && (_fdtab[fd].hnd == (HANDLE)-1)) + { + /* ignore writting errors to stdout and stderr. happens when we don't have a console installed */ + /* ### TODO replace this with something better */ + nwritten = count; + } + else + { + WCETRACE(WCE_IO, "_WriteFile: hnd %x error %d\n", _fdtab[fd].hnd, GetLastError()); + errno = EIO; + LeaveCriticalSection(&critsect); + return(-1); + } + } + } else if (_fdtab[fd].type == IO_FILE_TYPE_SOCKET) { + if ((nwritten = (int)send(fd, buf, count, 0)) == SOCKET_ERROR) { + /* werr = WSAGetLastError(); */ + werr = 1; + WCETRACE(WCE_IO, "send: sock %d error %d", _fdtab[fd].hnd, werr); + errno = _winerr2errno(werr); + LeaveCriticalSection(&critsect); + return(-1); + } + } else if (_fdtab[fd].type == IO_FILE_TYPE_NULL) { + // pretty normal, no? +// WCETRACE(WCE_IO, "warning - write called w/IO_FILE_TYPE_NULL"); + nwritten = count; + } + } else { + nwritten = _fdtab[fd].devops->write_r(reent, _fdtab[fd].fd, buf, count, _fdtab[fd].cxt); + } + + LeaveCriticalSection(&critsect); + return nwritten; +} + +off_t +_lseek_r(struct _reent *reent, int fd, off_t offset, int whence) { + off_t newpos; + int method; + WCETRACE(WCE_IO, "lseek(%d, %d, %d)", fd, offset, whence); + + FDCHECK(fd, 0); + + if (_fdtab[fd].devops == NULL) { + switch (whence) { + case SEEK_SET: + method = FILE_BEGIN; + break; + case SEEK_CUR: + method = FILE_CURRENT; + break; + case SEEK_END: + method = FILE_END; + break; + default: + method = FILE_BEGIN; + } + + if (_fdtab[fd].type == IO_FILE_TYPE_FILE) { + if ((newpos = _SetFilePointer(_fdtab[fd].hnd, (LONG)offset, NULL, (DWORD)method)) == -1) { + WCETRACE(WCE_IO, "_SetFilePointer(%x): error %d", _fdtab[fd].hnd, GetLastError()); + errno = EIO; + newpos = -1; + } + } else { + errno = EINVAL; + newpos = -1; + } + } else { + newpos = _fdtab[fd].devops->lseek_r(reent, _fdtab[fd].fd, offset, whence, _fdtab[fd].cxt); + } + + WCETRACE(WCE_IO, "lseek returns %d", newpos); + return(newpos); +} + +BOOL XCECopyFileW( + LPCWSTR lpExistingFileName, + LPCWSTR lpNewFileName, + BOOL bFailIfExists +); + +int +_link_r(struct _reent *reent, const char *old, const char *new) +{ + wchar_t wpathOld[MAX_PATH]; + wchar_t wpathNew[MAX_PATH]; + char pathOld[MAX_PATH]; + char pathNew[MAX_PATH]; + fixpath(old, pathOld); + fixpath(new, pathNew); + mbstowcs(wpathOld, pathOld, MAX_PATH); + mbstowcs(wpathNew, pathNew, MAX_PATH); + if(0==XCECopyFileW(wpathOld,wpathNew,FALSE)) + { +// printf("failed rename '%s' to '%s'\n",pathOld,pathNew); + errno = _winerr2errno(GetLastError()); + return(-1); + } + return 0; +} + +int +_unlink_r(struct _reent *reent, const char *path) +{ + wchar_t pathw[MAX_PATH]; + char pathbuf[MAX_PATH]; + BOOL res; + + if (path == NULL) + return(-1); + + fixpath(path, pathbuf); + mbstowcs(pathw, pathbuf, MAX_PATH); + res = DeleteFileW(pathw); + + if (res == FALSE) { + errno = _winerr2errno(GetLastError()); + return(-1); + } + + return(0); +} + +static int +_fd_to_socket(struct fd_set *set, int *hndmap) +{ + int i; + + if (set == NULL) + return(0); + + for (i = 0; i < set->fd_count; i++) { + int fd = (int)set->fd_array[i]; + FDCHECK(fd, 0); + + /* On WINCE, only IO_FILE_TYPE_SOCKET is handled */ + if (_fdtab[fd].type == IO_FILE_TYPE_SOCKET) { + SOCKET s = _fdtab[fd].sock; + hndmap[fd] = s; + WCETRACE(WCE_IO, "_fd_to_socket: fd = %d, handle = %d", fd, s); + set->fd_array[i] = s; + } else { + WCETRACE(WCE_IO, "_fd_to_socket: fd = %d is not a socket", fd); + } + } + return(0); +} + +static void +_socket_to_fd(fd_set *set, int *hndmap) +{ + int i, j, fd; + + if (set == NULL) + return; + + if (set->fd_count > MAXFDS) { + WCETRACE(WCE_IO, "select (_socket_to_fd) ERROR fd_count > MAXFDS (%d > %d)", + set->fd_count, MAXFDS); + } + + for (i = 0; i < set->fd_count; i++) { + fd = -1; + /* Hunt for matching hnd in the hndmap */ + for (j = 0; j < MAXFDS; j++) { + if (hndmap[j] == set->fd_array[i]) { + fd = j; + break; + } + } + + if (fd < 0 || fd > MAXFDS) { + WCETRACE(WCE_IO, "_socket_to_fd: ERROR weird fd %d", fd); + } else { + set->fd_array[i] = fd; + } + } +} + +#if 0 +int +select(int n, fd_set *rfds, fd_set* wfds, fd_set* xfds, struct timeval *timeout) +{ + int i; + int status; + fd_set r, w, x; + int werr, hndmap[MAXFDS]; + SOCKET s; + + WCETRACE(WCE_IO, "select(%d, %p, %p, %p, %p)", n, rfds, wfds, xfds, timeout); + if (timeout != NULL) { + WCETRACE(WCE_IO, "select: timeout {%d,%d}", timeout->tv_sec, timeout->tv_usec); + } + + /* Initialze hndmap - this is the SOCKET->fd mapping for use later */ + for (i = 0; i < MAXFDS; i++) + hndmap[i] = -1; + + if (rfds != NULL) { + if (_fd_to_socket(rfds, hndmap) < 0) { + WCETRACE(WCE_IO, "select: bad rfds"); + return(-1); + } + } + + if (wfds != NULL) { + if (_fd_to_socket(wfds, hndmap) < 0) { + WCETRACE(WCE_IO, "select: bad wfds"); + return(-1); + } + } + + if (xfds != NULL) { + if (_fd_to_socket(xfds, hndmap) < 0) { + WCETRACE(WCE_IO, "select: bad xfds"); + return(-1); + } + } + + status = __MS_select(n, rfds, wfds, xfds, timeout); + WCETRACE(WCE_IO, "select: returns %d errno %d", status, errno); + + /* Give up here if there is an select error */ + if (status == SOCKET_ERROR) { + int werr = XCEWSAGetLastError(); + errno = _winerr2errno(werr); + return(-1); + } + + /* Finally we must translate socket descriptors back to fds */ + if (rfds != NULL) + _socket_to_fd(rfds, hndmap); + + if (wfds != NULL) + _socket_to_fd(wfds, hndmap); + + if (xfds != NULL) + _socket_to_fd(xfds, hndmap); + + return(status); +} +#endif + +int +ioctl(int fd, unsigned int request, void *arg) +{ + DWORD high, low; + int length, pos, avail, *iptr; + int werr; + SOCKET s; + + WCETRACE(WCE_IO, "ioctl(%d, %p %p)", fd, request, arg); + + FDCHECK(fd, 0); + + if (_fdtab[fd].devops == NULL) { + if (_fdtab[fd].type == IO_FILE_TYPE_FILE) { + switch (request) { + case FIONREAD: + if (arg == NULL) { + errno = EINVAL; + return(-1); + } + low = GetFileSize(_fdtab[fd].hnd, &high); + + /* FIXME: Error checking */ + length = (int)(((long long)high) << 32L) | (long long)low; + WCETRACE(WCE_IO, "ioctl(%d (FIONREAD) length %d", fd, length); + + low = _SetFilePointer(_fdtab[fd].hnd, 0, (PLONG)&high, FILE_CURRENT); + if ((low == 0xffffffff) && (GetLastError() != NO_ERROR)) { + errno = EBADF; + return(-1); + } + + pos = (int)(((long long)high) << 32L) | (long long)low; + avail = length - pos; + WCETRACE(WCE_IO, "ioctl(%d (FIONREAD) pos %d avail %d", fd, pos, avail); + iptr = (int *)arg; + *iptr = (avail > 0) ? avail : 0; + return(0); + default: + errno = ENOSYS; + return(-1); + } + } else if (_fdtab[fd].type == IO_FILE_TYPE_SOCKET) { + s = _fdtab[fd].sock; + WCETRACE(WCE_IO, "ioctl: doing ioctlsocket w/0x%x (fd %d hnd %x)", request, fd, s); + if (ioctlsocket(fd, request, arg) == SOCKET_ERROR) { + /* werr = WSAGetLastError(); */ + werr = 1; + errno = _winerr2errno(werr); + return(-1); + } + } else if(_fdtab[fd].type == IO_FILE_TYPE_NULL) { + errno = ENOSYS; + return(-1); + } + } else { + return(_fdtab[fd].devops->ioctl_r(NULL, _fdtab[fd].fd, request, _fdtab[fd].cxt, arg)); + } + + return(0); +} + +int +_getpid_r(struct _reent *reent) +{ + int pid; + + pid = GetCurrentProcessId(); +// return pid & 0x7FFFFFFF; // pedro: Reiner, what is the rationale for this in celib? + return pid; +} + +int +isatty(int fd) +{ + WCETRACE(WCE_IO, "isatty(%d)", fd); + + if (!fdsinitialized) + return(FALSE); + + if (_fdtab[fd].type == IO_FILE_TYPE_CONSOLE || + _fdtab[fd].type == IO_FILE_TYPE_FIFO) { + WCETRACE(WCE_IO, "isatty(%d): yes", fd); + return(TRUE); + } + + WCETRACE(WCE_IO, "isatty(%d): no", fd); + return(FALSE); +} + +int +ftruncate(int fd, off_t size) +{ + DWORD newpos; + + FDCHECK(fd, 0); + + if (_fdtab[fd].type != IO_FILE_TYPE_FILE) { + errno = EBADF; + return -1; + } + + if ((newpos = _SetFilePointer(_fdtab[fd].hnd, size, NULL, + FILE_BEGIN)) == -1) + { + errno = _winerr2errno(GetLastError()); + return -1; + } + + if(!SetEndOfFile(_fdtab[fd].hnd)) + { + errno = _winerr2errno(GetLastError()); + return -1; + } + + return 0; +} + +// TODO: The fd entry is simply copied. When one of the files +// is closed, the handle is also closed! There should be a +// refcount on the handles! That would require another table. + +// TODO: Consider using DuplicateHandle here. + +int +dup(int fd) +{ + int newfd; + + + newfd = _getnewfd(); + + if(newfd >= 0) + memcpy(&_fdtab[newfd], &_fdtab[fd], sizeof(_fdent_t)); + + return newfd; +} + +int +dup2(int fd1, int fd2) +{ + if(fd2 < 0 || fd2 >= MAXFDS); + { + errno = EBADF; + return -1; + } + + if(_fdtab[fd2].fd != -1) + close(fd2); + + memcpy(&_fdtab[fd2], &_fdtab[fd1], sizeof(_fdent_t)); + + return fd2; +} Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/stat.c =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/stat.c 2008-08-01 20:35:28 UTC (rev 1168) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/stat.c 2008-08-30 07:46:02 UTC (rev 1169) @@ -21,7 +21,7 @@ WCETRACE(WCE_IO, "fstat(%d)", fd); - FDCHECK(fd); + FDCHECK(fd, 0); #if 0 static int first_time = 1; Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/io.h =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/io.h 2008-08-01 20:35:28 UTC (rev 1168) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/io.h 2008-08-30 07:46:02 UTC (rev 1169) @@ -34,11 +34,12 @@ _DEVOPS devops; } _fdent_t; -#define FDCHECK(F) \ +#define FDCHECK(F, CS) \ do { \ if (F < 0 || F >= MAXFDS || _fdtab[F].fd == -1) { \ WCETRACE(WCE_IO, "Invalid file handle: %d", F); \ errno = EBADF; \ + if (CS) { LeaveCriticalSection(CS); } \ return(-1); \ } \ } while (0) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2008-08-30 07:52:12
|
Revision: 1170 http://cegcc.svn.sourceforge.net/cegcc/?rev=1170&view=rev Author: dannybackx Date: 2008-08-30 07:52:10 +0000 (Sat, 30 Aug 2008) Log Message: ----------- Implement fsync and fdatasync Modified Paths: -------------- trunk/cegcc/src/newlib/ChangeLog.cegcc trunk/cegcc/src/newlib/newlib/libc/sys/wince/io.c Modified: trunk/cegcc/src/newlib/ChangeLog.cegcc =================================================================== --- trunk/cegcc/src/newlib/ChangeLog.cegcc 2008-08-30 07:46:02 UTC (rev 1169) +++ trunk/cegcc/src/newlib/ChangeLog.cegcc 2008-08-30 07:52:10 UTC (rev 1170) @@ -1,6 +1,7 @@ 2008-08-29 Pawel Veselov <paw...@gm...> + * newlib/libc/sys/wince/io.c (fsync, fdatasync) : Implement. * newlib/libc/sys/wince/sys/io.h newlib/libc/sys/wince/io.c - newlib/libc/sys/wince/stat.c : add critical section parameter + newlib/libc/sys/wince/stat.c : Add critical section parameter to FDCHECK to prevent deadlock when FDCHECK returns. 2008-06-10 Danny Backx <dan...@us...> Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/io.c =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/io.c 2008-08-30 07:46:02 UTC (rev 1169) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/io.c 2008-08-30 07:52:10 UTC (rev 1170) @@ -5,6 +5,7 @@ #include <stdio.h> #include <sys/stat.h> #include <string.h> +#include <sys/unistd.h> #include <fcntl.h> #include <reent.h> #include <errno.h> @@ -99,6 +100,21 @@ LeaveCriticalSection(&critsect); } +int fsync(int fd) { + WCETRACE(WCE_IO, "syncing descriptor %d", fd); + FDCHECK(fd, 0); + if (FlushFileBuffers(_fdtab[fd].hnd)) { + errno = _winerr2errno(GetLastError()); + WCETRACE(WCE_IO, "FlushFileBuffers(%d): errno=%d oserr=%d\n", fd, errno, GetLastError()); + return -1; + } + return 0; +} + +int fdatasync(int fd) { + return fsync(fd); +} + void _initfds() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2008-09-16 15:57:05
|
Revision: 1177 http://cegcc.svn.sourceforge.net/cegcc/?rev=1177&view=rev Author: dannybackx Date: 2008-09-16 22:57:02 +0000 (Tue, 16 Sep 2008) Log Message: ----------- 2008-09-12 Pawel Veselov <paw...@gm...> * newlib/newlib/libc/include/stdlib.h : added realpath() declaration * newlib/libc/sys/wince/Makefile.in newlib/libc/sys/wince/Makefile.am : compile realpath.c * newlib/libc/sys/wince/sys/unistd.h : declare fdatasync() * newlib/libc/sys/wince/realpath.c : defines realpath(), Linux compliant * newlib/libc/sys/wince/getcwd.c : buffer is now allocated if NULL. ENOENT is returned if current directory doesn't exist Modified Paths: -------------- trunk/cegcc/src/newlib/ChangeLog.cegcc trunk/cegcc/src/newlib/newlib/libc/include/stdlib.h trunk/cegcc/src/newlib/newlib/libc/sys/wince/Makefile.am trunk/cegcc/src/newlib/newlib/libc/sys/wince/Makefile.in trunk/cegcc/src/newlib/newlib/libc/sys/wince/getcwd.c trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/unistd.h Added Paths: ----------- trunk/cegcc/src/newlib/newlib/libc/sys/wince/realpath.c Modified: trunk/cegcc/src/newlib/ChangeLog.cegcc =================================================================== --- trunk/cegcc/src/newlib/ChangeLog.cegcc 2008-09-16 22:44:29 UTC (rev 1176) +++ trunk/cegcc/src/newlib/ChangeLog.cegcc 2008-09-16 22:57:02 UTC (rev 1177) @@ -1,3 +1,12 @@ +2008-09-12 Pawel Veselov <paw...@gm...> + * newlib/newlib/libc/include/stdlib.h : added realpath() declaration + * newlib/libc/sys/wince/Makefile.in newlib/libc/sys/wince/Makefile.am : + compile realpath.c + * newlib/libc/sys/wince/sys/unistd.h : declare fdatasync() + * newlib/libc/sys/wince/realpath.c : defines realpath(), Linux compliant + * newlib/libc/sys/wince/getcwd.c : buffer is now allocated if NULL. + ENOENT is returned if current directory doesn't exist + 2008-08-29 Pawel Veselov <paw...@gm...> * newlib/libc/sys/wince/io.c (fsync, fdatasync) : Implement. * newlib/libc/sys/wince/sys/io.h newlib/libc/sys/wince/io.c Modified: trunk/cegcc/src/newlib/newlib/libc/include/stdlib.h =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/include/stdlib.h 2008-09-16 22:44:29 UTC (rev 1176) +++ trunk/cegcc/src/newlib/newlib/libc/include/stdlib.h 2008-09-16 22:57:02 UTC (rev 1177) @@ -122,6 +122,7 @@ int _EXFUN(system,(const char *__string)); #ifndef __STRICT_ANSI__ +char * _EXFUN(realpath,(const char *__path, char *__resolved_path)); long _EXFUN(a64l,(const char *__input)); char * _EXFUN(l64a,(long __input)); char * _EXFUN(_l64a_r,(struct _reent *,long __input)); Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/Makefile.am =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/Makefile.am 2008-09-16 22:44:29 UTC (rev 1176) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/Makefile.am 2008-09-16 22:57:02 UTC (rev 1177) @@ -8,7 +8,7 @@ net_SOURCES = ascii2addr.c htons.c htonl.c inet_aton.c inet_lnaof.c inet_mkadr.c \ inet_net.c inet_netof.c inet_ntoa.c msnet.c wsdb.c rexec.c wsstrerror.c -unix_SOURCES = getcwd.c getlogin.c sleep.c usleep.c vfork.c +unix_SOURCES = getcwd.c getlogin.c sleep.c usleep.c vfork.c realpath.c celib_SOURCES = cecopyfile.c cefileattr.c cefindfile.c cefixpath.c ceirda.c ceutil.c cethread.c cemakeunixpath.c \ cemovefile.c cecreatefile.c cecreatefilemap.c ceregistry.c cecurrentdir.c ceprofile.c \ ceshared2.c ceremovedir.c cemisc.c Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/Makefile.in =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/Makefile.in 2008-09-16 22:44:29 UTC (rev 1176) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/Makefile.in 2008-09-16 22:57:02 UTC (rev 1177) @@ -86,7 +86,7 @@ net_SOURCES = ascii2addr.c htons.c htonl.c inet_aton.c inet_lnaof.c inet_mkadr.c inet_net.c inet_netof.c inet_ntoa.c msnet.c wsdb.c rexec.c wsstrerror.c -unix_SOURCES = getcwd.c getlogin.c sleep.c usleep.c vfork.c +unix_SOURCES = getcwd.c getlogin.c sleep.c usleep.c vfork.c realpath.c celib_SOURCES = cecopyfile.c cefileattr.c cefindfile.c cefixpath.c ceirda.c ceutil.c cethread.c cemakeunixpath.c cemovefile.c cecreatefile.c cecreatefilemap.c ceregistry.c cecurrentdir.c ceprofile.c ceshared2.c ceremovedir.c cemisc.c @@ -116,7 +116,7 @@ trace.o tzset_hook_r.o uid.o unistd.o utime.o main.o ascii2addr.o \ htons.o htonl.o inet_aton.o inet_lnaof.o inet_mkadr.o inet_net.o \ inet_netof.o inet_ntoa.o msnet.o wsdb.o rexec.o wsstrerror.o getcwd.o \ -getlogin.o sleep.o usleep.o vfork.o cecopyfile.o cefileattr.o \ +getlogin.o realpath.o sleep.o usleep.o vfork.o cecopyfile.o cefileattr.o \ cefindfile.o cefixpath.o ceirda.o ceutil.o cethread.o cemakeunixpath.o \ cemovefile.o cecreatefile.o cecreatefilemap.o ceregistry.o \ cecurrentdir.o ceprofile.o ceshared2.o ceremovedir.o cemisc.o _crt_mt.o \ Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/getcwd.c =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/getcwd.c 2008-09-16 22:44:29 UTC (rev 1176) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/getcwd.c 2008-09-16 22:57:02 UTC (rev 1177) @@ -68,9 +68,33 @@ char * getcwd(char *buf, size_t size) { - /* This is NOT compliant with what Linux does.. */ - if (buf == NULL || size == 0) { - /* ### TODO malloc a buffer here. Be careful with size-1 below */ + + int alloced = 0; + + // realize glibc behavior to allocate buffer if the buf is 0. + // This is also a POSIX.1-2001 extension + + if (!buf) { + if (!size) { + size = XCEGetCurrentDirectoryW(0, 0); // fastest way to get size + if (!size) { + WCETRACE(WCE_IO, "getcwd WARNING: curr dir is unset"); + // ENOENT The current working directory has been unlinked. + errno = ENOENT; + return NULL; + } + } + + buf = malloc(size); + if (!buf) { + errno = ENOMEM; + return NULL; + } + alloced = 1; + + } else if (!size) { + // EINVAL The size argument is zero and buf is not a null pointer. + errno = EINVAL; return(NULL); } @@ -78,18 +102,32 @@ if (len > size) { - XCEToUnixPath(buf, size-1); - errno = ERANGE; - return(NULL); + // XCEToUnixPath(buf, size-1); + // ^^ commented out, why do we care? the spec says: + // the contents of the array pointed to by buf is undefined on error. + errno = ERANGE; + return(NULL); } else if (!len) { - WCETRACE(WCE_IO, "getcwd WARNING: curr dir is unset"); - return NULL; + WCETRACE(WCE_IO, "getcwd WARNING: curr dir is unset"); + // ENOENT The current working directory has been unlinked. + // well, that's the next best thing + errno = ENOENT; + return NULL; } else { - XCEToUnixPath(buf, -1); + struct stat st; + XCEToUnixPath(buf, -1); + if (lstat(buf, &st)) { + // ENOENT The current working directory has been unlinked. + if (alloced) { + free(buf); + } + errno = ENOENT; + return NULL; + } } return buf; } Added: trunk/cegcc/src/newlib/newlib/libc/sys/wince/realpath.c =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/realpath.c (rev 0) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/realpath.c 2008-09-16 22:57:02 UTC (rev 1177) @@ -0,0 +1,165 @@ +/* realpath.c - Return the canonicalized absolute pathname */ + +/* Written 2000 by Werner Almesberger */ +/* Adapted for WINCE */ + +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <limits.h> +#include <errno.h> +#include <sys/stat.h> + +char *realpath(const char *path, char *resolved_path) { + + char *path_copy; + char *aptr; + int res; + int alloced = 0; + + if (!path) { + errno = EINVAL; + return NULL; + } else if (!*path) { + errno = ENOENT; + return NULL; + } + + path_copy = strdup(path); + if (!path_copy) { + errno = ENOMEM; + return NULL; + } + + // Since this is wince, there is no way we can have '\' characters + // in file/dir names. So we might as well replace them with '/', won't + // change nothing. + + aptr = path_copy; + while (aptr = strchr(aptr, '\\')) { *(aptr++) = '/'; } + + if (*path_copy != '/') { + + // then we need current directory + char * cwd = getcwd(0,0); + if (!cwd) { + // this should only be ENOENT, or ENOMEM + free(path_copy); + return NULL; + } + + aptr = malloc(strlen(cwd) + strlen(path_copy) + 2); + + if (aptr) { + strcpy(aptr, cwd); + strcat(aptr, "/"); + strcpy(aptr, path_copy); + } + + free(path_copy); + free(cwd); + if (!aptr) { + errno = ENOMEM; + return NULL; + } + path_copy = aptr; + } + + // remove any trailing slashes + aptr = path_copy + strlen(path_copy) - 1; + while (aptr > path_copy && *aptr == '/') { *(aptr--) = 0; } + + if (!resolved_path) { + // since there are no symlinks on WinCE, we are lucky, + // the resolved path will never exceed this path + resolved_path = malloc(strlen(path_copy)+1); + alloced = 1; + } + + *resolved_path = '/'; + resolved_path[1] = 0; // ought to be faster than strcpy + + aptr = path_copy; + struct stat st; + + while (1) { + + while (*aptr == '/') { aptr++; } + + // are we done? + if (!*aptr) { break; } + + // find next slash + char * slash = strchr(aptr, '/'); + if (slash) { + *slash = 0; + } + + if (*aptr == '.') { + if (!aptr[1]) { + // encountered "." + // nothing to do + if (!slash) { break; } + aptr = slash + 1; + continue; + } + if (aptr[1] == '.' && !aptr[2]) { + // encountered ".." + // so rewind the path one element back + char * prev_slash = strrchr(resolved_path, '/'); + if (prev_slash == resolved_path) { + // if the only thing in the path now is the + // root, then the root just remains there + prev_slash++; + } + *prev_slash = 0; + + if (!slash) { break; } + aptr = slash + 1; + continue; + } + } + + if (resolved_path[1]) { + strcat(resolved_path, "/"); + } + + strcat(resolved_path, aptr); + + if (slash) { + + if (lstat(resolved_path, &st)) { + + if (alloced) { + free(resolved_path); + } + free(path_copy); + + errno = EACCES; + return NULL; + + } + + if (!(st.st_mode & S_IFDIR)) { + // there are more entries ahead, but this one is + // not a directory. tsk-tsk + if (alloced) { free(resolved_path); } + free(path_copy); + errno = ENOTDIR; + return NULL; + } + + } else { + break; + } + + aptr = slash + 1; + continue; + + } + + free(path_copy); + return resolved_path; + +} + Property changes on: trunk/cegcc/src/newlib/newlib/libc/sys/wince/realpath.c ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/unistd.h =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/unistd.h 2008-09-16 22:44:29 UTC (rev 1176) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/unistd.h 2008-09-16 22:57:02 UTC (rev 1177) @@ -21,6 +21,7 @@ int _EXFUN(chdir, (const char *__path )); int _EXFUN(chmod, (const char *__path, mode_t __mode )); int _EXFUN(chown, (const char *__path, uid_t __owner, gid_t __group )); +int _EXFUN(fdatasync, (int __fd)); #if defined(__CYGWIN__) || defined(__rtems__) int _EXFUN(chroot, (const char *__path )); #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ped...@us...> - 2008-09-24 01:22:54
|
Revision: 1187 http://cegcc.svn.sourceforge.net/cegcc/?rev=1187&view=rev Author: pedroalves Date: 2008-09-24 01:22:47 +0000 (Wed, 24 Sep 2008) Log Message: ----------- 2008-09-24 Pedro Alves <ped...@us...> * config.sub: Add cegcc support. * configure.in: Adjust to allow arm-cegcc. * configure: Regenerate. newlib/ * configure.host: Adjust to allow arm-cegcc. Modified Paths: -------------- trunk/cegcc/src/newlib/ChangeLog.cegcc trunk/cegcc/src/newlib/config.sub trunk/cegcc/src/newlib/configure trunk/cegcc/src/newlib/configure.in trunk/cegcc/src/newlib/newlib/configure.host Modified: trunk/cegcc/src/newlib/ChangeLog.cegcc =================================================================== --- trunk/cegcc/src/newlib/ChangeLog.cegcc 2008-09-24 01:15:16 UTC (rev 1186) +++ trunk/cegcc/src/newlib/ChangeLog.cegcc 2008-09-24 01:22:47 UTC (rev 1187) @@ -1,3 +1,12 @@ +2008-09-24 Pedro Alves <ped...@us...> + + * config.sub: Add cegcc support. + * configure.in: Adjust to allow arm-cegcc. + * configure: Regenerate. + + newlib/ + * configure.host: Adjust to allow arm-cegcc. + 2008-09-12 Pawel Veselov <paw...@gm...> * newlib/newlib/libc/include/stdlib.h : added realpath() declaration * newlib/libc/sys/wince/Makefile.in newlib/libc/sys/wince/Makefile.am : Modified: trunk/cegcc/src/newlib/config.sub =================================================================== --- trunk/cegcc/src/newlib/config.sub 2008-09-24 01:15:16 UTC (rev 1186) +++ trunk/cegcc/src/newlib/config.sub 2008-09-24 01:22:47 UTC (rev 1187) @@ -446,6 +446,10 @@ basic_machine=c90-cray os=-unicos ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; convex-c1) basic_machine=c1-convex os=-bsd Modified: trunk/cegcc/src/newlib/configure =================================================================== --- trunk/cegcc/src/newlib/configure 2008-09-24 01:15:16 UTC (rev 1186) +++ trunk/cegcc/src/newlib/configure 2008-09-24 01:22:47 UTC (rev 1187) @@ -1241,7 +1241,7 @@ sh-*-linux*) noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss" ;; - sh*-*-pe|mips*-*-pe|*arm-wince-pe|*arm-wince-cegcc) + sh*-*-pe | mips*-*-pe | arm*-wince-pe | arm*-*-cegcc) noconfigdirs="$noconfigdirs target-libgloss" noconfigdirs="$noconfigdirs ${libgcj}" noconfigdirs="$noconfigdirs target-examples" Modified: trunk/cegcc/src/newlib/configure.in =================================================================== --- trunk/cegcc/src/newlib/configure.in 2008-09-24 01:15:16 UTC (rev 1186) +++ trunk/cegcc/src/newlib/configure.in 2008-09-24 01:22:47 UTC (rev 1187) @@ -449,7 +449,7 @@ sh-*-linux*) noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss" ;; - sh*-*-pe|mips*-*-pe|*arm-wince-pe|*arm-wince-cegcc) + sh*-*-pe | mips*-*-pe | arm*-wince-pe | arm*-*-cegcc) noconfigdirs="$noconfigdirs target-libgloss" noconfigdirs="$noconfigdirs ${libgcj}" noconfigdirs="$noconfigdirs target-examples" Modified: trunk/cegcc/src/newlib/newlib/configure.host =================================================================== --- trunk/cegcc/src/newlib/newlib/configure.host 2008-09-24 01:15:16 UTC (rev 1186) +++ trunk/cegcc/src/newlib/newlib/configure.host 2008-09-24 01:22:47 UTC (rev 1187) @@ -320,7 +320,7 @@ arc-*-*) sys_dir=arc ;; - arm-wince-pe | arm-wince-cegcc) + arm-wince-pe | arm*-*-cegcc) sys_dir=wince unix_dir=unix ;; @@ -507,17 +507,17 @@ arm-wince-pe) syscall_dir=syscalls #no really srcdir yet, but will be. for now it makes my life easier to point into ${prefix} - test -z "$cegcc_srcdir" && cegcc_srcdir=`cd ${prefix}/arm-wince-pe/include; pwd` + test -z "$cegcc_srcdir" && cegcc_srcdir=`cd ${prefix}/${host}/include; pwd` export cegcc_srcdir newlib_cflags="${newlib_cflags} -mwin32 -idirafter ${cegcc_srcdir}/w32api -march=armv4 -DGNUWINCE -DSARM -DABORT_PROVIDED -DMALLOC_PROVIDED -DWANT_PRINTF_LONG_LONG -D_COMPILING_NEWLIB -DREENTRANT_SYSCALLS_PROVIDED -DNO_FORK" default_newlib_io_long_long="yes" default_newlib_io_long_double="yes" default_newlib_io_pos_args="yes" ;; - arm-wince-cegcc) + arm*-*-cegcc*) syscall_dir=syscalls #no really srcdir yet, but will be. for now it makes my life easier to point into ${prefix} - test -z "$cegcc_srcdir" && cegcc_srcdir=`cd ${prefix}/arm-wince-cegcc/include; pwd` + test -z "$cegcc_srcdir" && cegcc_srcdir=`cd ${prefix}/${host}/include; pwd` export cegcc_srcdir newlib_cflags="${newlib_cflags} -mwin32 -idirafter ${cegcc_srcdir}/w32api -march=armv4 -DGNUWINCE -DSARM -DABORT_PROVIDED -DMALLOC_PROVIDED -DWANT_PRINTF_LONG_LONG -D_COMPILING_NEWLIB -DREENTRANT_SYSCALLS_PROVIDED -DNO_FORK" default_newlib_io_long_long="yes" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ped...@us...> - 2008-10-04 21:41:02
|
Revision: 1196 http://cegcc.svn.sourceforge.net/cegcc/?rev=1196&view=rev Author: pedroalves Date: 2008-10-04 21:40:55 +0000 (Sat, 04 Oct 2008) Log Message: ----------- 2008-10-04 Pawel Veselov <paw...@gm...> newlib/ * libc/sys/wince/sys/shared.h (_shared_getshowwindow): Redefine to include _SHMBLK argument. * libc/sys/wince/sys/shared.h (_shared_getenvironblk): Redefine to return int. Add a comment explaining what the function does. * libc/sys/wince/startup.c (inherit_parent): Don't call _shared_getenvblk there, it's called somewhere else. * libc/sys/wince/env.c (_initenv): Use new _shared_getenvironblk semantics. * libc/sys/wince/spawn.c (_spawnv, _spawnvp, _newlib_pre_spawn): Use correct function name. * libc/sys/wince/shared.c: Rename _shared_setenvblk to _shared_setenvironblk to match the header file definition. * libc/sys/wince/shared.c (_shared_getenvironblk): Allocate memory for the copy of the shared environment block, and return the number of variables found. Modified Paths: -------------- trunk/cegcc/src/newlib/ChangeLog.cegcc trunk/cegcc/src/newlib/newlib/libc/sys/wince/env.c trunk/cegcc/src/newlib/newlib/libc/sys/wince/shared.c trunk/cegcc/src/newlib/newlib/libc/sys/wince/spawn.c trunk/cegcc/src/newlib/newlib/libc/sys/wince/startup.c trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/shared.h Modified: trunk/cegcc/src/newlib/ChangeLog.cegcc =================================================================== --- trunk/cegcc/src/newlib/ChangeLog.cegcc 2008-09-30 11:56:35 UTC (rev 1195) +++ trunk/cegcc/src/newlib/ChangeLog.cegcc 2008-10-04 21:40:55 UTC (rev 1196) @@ -1,3 +1,22 @@ +2008-10-04 Pawel Veselov <paw...@gm...> + + newlib/ + * libc/sys/wince/sys/shared.h (_shared_getshowwindow): Redefine to + include _SHMBLK argument. + * libc/sys/wince/sys/shared.h (_shared_getenvironblk): Redefine to + return int. Add a comment explaining what the function does. + * libc/sys/wince/startup.c (inherit_parent): Don't call + _shared_getenvblk there, it's called somewhere else. + * libc/sys/wince/env.c (_initenv): Use new _shared_getenvironblk + semantics. + * libc/sys/wince/spawn.c (_spawnv, _spawnvp, _newlib_pre_spawn): + Use correct function name. + * libc/sys/wince/shared.c: Rename _shared_setenvblk to + _shared_setenvironblk to match the header file definition. + * libc/sys/wince/shared.c (_shared_getenvironblk): Allocate memory + for the copy of the shared environment block, and return the + number of variables found. + 2008-09-24 Pedro Alves <ped...@us...> * config.sub: Add cegcc support. Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/env.c =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/env.c 2008-09-30 11:56:35 UTC (rev 1195) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/env.c 2008-10-04 21:40:55 UTC (rev 1196) @@ -28,14 +28,14 @@ if((res = XCERegOpenKeyExA(HKEY_LOCAL_MACHINE, "Environment", 0, KEY_READ, &hKey)) != 0) - { - // use defaults - putenv("UNIXROOTDIR=/"); - putenv("PATH=.:/:/Windows"); - putenv("HOME=/My Documents"); - putenv("TMP=/Temp"); - return; - } + { + // use defaults + putenv("UNIXROOTDIR=/"); + putenv("PATH=.:/:/Windows"); + putenv("HOME=/My Documents"); + putenv("TMP=/Temp"); + return; + } while(1) { @@ -48,9 +48,7 @@ if(res != 0) { if(res != ERROR_NO_MORE_ITEMS) - { XCEShowMessageA("RegEnumValue: %d", res); - } break; } @@ -79,21 +77,24 @@ void _initenv(_SHMBLK shmblk) { if (shmblk) - { - char buf[MAX_ENVIRONBLK]; + { + char *buf; + int no; - /* We are being initialized from a cegcc app. - Kill environ set from the registry. */ - environ[0] = 0; - _shared_getenvblk(shmblk, buf); - if(buf[0] != 0) - _initenv_from_envblock(buf); - else - _initenv_from_reg(); - _shared_setenvblk(shmblk, ""); + /* We are being initialized from a cegcc app. Only use the + registry environment if there are no environment variables in + the shared block. */ + + no = _shared_getenvironblk(shmblk, &buf); + + if (no) + { + _initenv_from_envblock(buf); + free(buf); + } + else + _initenv_from_reg(); } else - { - _initenv_from_reg(); - } + _initenv_from_reg(); } Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/shared.c =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/shared.c 2008-09-30 11:56:35 UTC (rev 1195) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/shared.c 2008-10-04 21:40:55 UTC (rev 1196) @@ -194,7 +194,7 @@ } void -_shared_setenvblk(_SHMBLK shmblk, char **env) +_shared_setenvironblk(_SHMBLK shmblk, char **env) { char *d; int i, len; @@ -209,7 +209,8 @@ for (i = 0, d = shmblk->pginfo.environ; env[i] != NULL; i++) { len = strlen(env[i]); if (d + len >= endp) { - WCETRACE(WCE_IO, "_shared_setenvblk: FATAL space exhausted (max %d)", + WCETRACE(WCE_IO, "_shared_setenvironblk: " + "FATAL space exhausted (max %d)", MAX_ENVIRONBLK); exit(1); } @@ -219,28 +220,33 @@ *d = 0; } -void -_shared_getenvblk(_SHMBLK shmblk, char **env) +int +_shared_getenvironblk(_SHMBLK shmblk, char **env) { char *s; int i, len; - if (shmblk == NULL) - return; + if (shmblk == NULL) { + return 0; + } for (i = 0, s = shmblk->pginfo.environ; *s; i++) { - len = strlen(s); - if (env[i] != NULL) { - free(env[i]); - } - env[i] = malloc(len + 1); - if (env[i] == NULL) { - WCETRACE(WCE_IO, "_shared_getenvblk: FATAL ERROR malloc failed"); - exit(1); - } - memcpy(env[i], s, len + 1); - s += len + 1; - } + s += strlen(s) + 1; + } + + if (i) { + len = s - shmblk->pginfo.environ + 1; + *env = malloc(len); + if (*env == NULL) { + WCETRACE(WCE_IO, "_shared_getenvironblk: " + "FATAL ERROR malloc failed for %d more bytes", len); + exit(1); + } + + memcpy(*env, shmblk->pginfo.environ, len); + } + + return i; } BOOL Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/spawn.c =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/spawn.c 2008-09-30 11:56:35 UTC (rev 1195) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/spawn.c 2008-10-04 21:40:55 UTC (rev 1196) @@ -93,7 +93,7 @@ } WCETRACE(WCE_IO, "spawnv: _shared_init returns %x", shmblk); - _shared_setenvblk(shmblk, environ); + _shared_setenvironblk(shmblk, environ); getcwd(buf, BUFSIZE); WCETRACE(WCE_IO, "spawnv: cwd \"%s\"", buf); _shared_setcwd(shmblk, buf); @@ -155,7 +155,7 @@ } WCETRACE(WCE_IO, "spawnv: _shared_init returns %x", shmblk); - _shared_setenvblk(shmblk, environ); + _shared_setenvironblk(shmblk, environ); getcwd(buf, BUFSIZE); WCETRACE(WCE_IO, "spawnvp: cwd \"%s\"", buf); _shared_setcwd(shmblk, buf); @@ -190,7 +190,7 @@ return(-1); } - _shared_setenvblk(shmblk, environ); + _shared_setenvironblk(shmblk, environ); getcwd(buf, BUFSIZE); _shared_setcwd(shmblk, buf); _shared_setstdinfd(shmblk, (infd >= 0) ? _fdtab[infd].fd : infd); Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/startup.c =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/startup.c 2008-09-30 11:56:35 UTC (rev 1195) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/startup.c 2008-10-04 21:40:55 UTC (rev 1196) @@ -548,7 +548,6 @@ atexit(_ioatexit); _shared_dump(shmblk); - _shared_getenvblk(shmblk, environ); __pgid = _shared_getpgid(shmblk); _shared_getcwd(shmblk, buf); Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/shared.h =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/shared.h 2008-09-30 11:56:35 UTC (rev 1195) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/shared.h 2008-10-04 21:40:55 UTC (rev 1196) @@ -30,10 +30,15 @@ _SHMBLK _shared_init(int pgid); void _shared_dump(_SHMBLK shmblk); -int _shared_getshowwindow(); +int _shared_getshowwindow(_SHMBLK shmblk); void _shared_setshowwindow(_SHMBLK shmblk, int show); void _shared_setenvironblk(_SHMBLK shmblk, char **env); -void _shared_getenvironblk(_SHMBLK shmblk, char **env); + +/* Returns the number of environment variables extracted from the + shared block. The environment variables are written into *ENV, + which is allocated using malloc. */ +int _shared_getenvironblk(_SHMBLK shmblk, char **env); + void _shared_reset(_SHMBLK shmblk); void _shared_getcwd(_SHMBLK shmblk, char *cwd); void _shared_setcwd(_SHMBLK shmblk, char *cwd); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ped...@us...> - 2008-10-09 00:51:21
|
Revision: 1200 http://cegcc.svn.sourceforge.net/cegcc/?rev=1200&view=rev Author: pedroalves Date: 2008-10-09 00:51:10 +0000 (Thu, 09 Oct 2008) Log Message: ----------- 2008-10-09 Pawel Veselov <paw...@gm...> newlib/ * libc/sys/wince/trace.c (__trace_closed): New. (get_level_name): New. (WCETRACE): Rename to... (__WCETrace): ... this. (WCETRACESET): Do not change the trace level if the tracing facilities have been closed. (WCETRACECLOSE): Print out a message that the tracing has closed. Reset tracing level to 0 after closing. (__WCETrace): Print out the tracing level along with the message. * libc/sys/wince/sys/wcetrace.h (WCETRACE): Define. (WCETRACE): Rename to ... (__WCETrace): ... this. (WCETRACING): Define. * libc/sys/wince/io.c (_write_r): When tracing out stdio/stderr buffer, send out as many bytes as are in the buffer, instead of using zero termination. Modified Paths: -------------- trunk/cegcc/src/newlib/ChangeLog.cegcc trunk/cegcc/src/newlib/newlib/libc/sys/wince/io.c trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/wcetrace.h trunk/cegcc/src/newlib/newlib/libc/sys/wince/trace.c Modified: trunk/cegcc/src/newlib/ChangeLog.cegcc =================================================================== --- trunk/cegcc/src/newlib/ChangeLog.cegcc 2008-10-07 17:03:04 UTC (rev 1199) +++ trunk/cegcc/src/newlib/ChangeLog.cegcc 2008-10-09 00:51:10 UTC (rev 1200) @@ -1,3 +1,23 @@ +2008-10-09 Pawel Veselov <paw...@gm...> + + newlib/ + * libc/sys/wince/trace.c (__trace_closed): New. + (get_level_name): New. + (WCETRACE): Rename to... + (__WCETrace): ... this. + (WCETRACESET): Do not change the trace level if the tracing + facilities have been closed. + (WCETRACECLOSE): Print out a message that the tracing has closed. + Reset tracing level to 0 after closing. + (__WCETrace): Print out the tracing level along with the message. + * libc/sys/wince/sys/wcetrace.h (WCETRACE): Define. + (WCETRACE): Rename to ... + (__WCETrace): ... this. + (WCETRACING): Define. + * libc/sys/wince/io.c (_write_r): When tracing out stdio/stderr + buffer, send out as many bytes as are in the buffer, instead of + using zero termination. + 2008-10-04 Pawel Veselov <paw...@gm...> newlib/ Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/io.c =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/io.c 2008-10-07 17:03:04 UTC (rev 1199) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/io.c 2008-10-09 00:51:10 UTC (rev 1200) @@ -515,13 +515,14 @@ WCETRACE(WCE_IO, "write(%d, %d, %x)", fd, count, _fdtab[fd].hnd); EnterCriticalSection(&critsect); -#if 1 - if (fd == 2 || fd == 1) - { - const char* out = fd == 2?"stderr: ":"stdout: "; - WCETRACE(WCE_IO, "%s : %s", out, buf); + + if (WCETRACING(WCE_IO)) { + if (fd == 2 || fd == 1) { + char fmt[30]; + snprintf(fmt, 29, "%s : %%.%ds", fd == 2?"stderr":"stdout", count); + WCETRACE(WCE_IO, fmt, buf); + } } -#endif /* until we can call console stuff inside the PE loader */ if ((!__StdioInited) && (fd >= 0) && (fd <= 2)) Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/wcetrace.h =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/wcetrace.h 2008-10-07 17:03:04 UTC (rev 1199) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/sys/wcetrace.h 2008-10-09 00:51:10 UTC (rev 1200) @@ -32,16 +32,26 @@ #endif #ifndef CE_NOTRACE + void WCETRACEGETENV(void); void WCETRACESET(int trace); int WCETRACEGET(void); -void WCETRACE(int level, const char *fmt, ...); +#define WCETRACING(LEVEL) \ + ((WCETRACE_DEBUGGER_GET() & (LEVEL)) || (WCETRACEGET() & (LEVEL))) +#define WCETRACE(LEVEL, FMT...) do { \ + if (WCETRACING(LEVEL)) \ + __WCETrace(LEVEL, FMT); \ + } while(0) + void WCETRACE_DEBUGGER_SET(int trace); int WCETRACE_DEBUGGER_GET(void); void WCETRACECLOSE(void); +void __WCETrace(int trace, const char * fmt, ...); void __WCETraceError(int level, unsigned long werr, const char* funct); #define WCETRACE_ERROR(T, ERR) __WCETraceError(T, ERR, __FUNCTION__) + #else + #define WCETRACEGETENV() do {} while (0) #define WCETRACESET(trace) do {} while (0) #define WCETRACEGET() do {} while (0) @@ -50,6 +60,8 @@ #define WCETRACE_DEBUGGER_GET() do {} while (0) #define WCETRACECLOSE() do {} while (0) #define WCETRACE_ERROR(T, ERR) do {} while (0) +#define WCETRACING(p) (0) + #endif #ifdef __cplusplus Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/trace.c =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/trace.c 2008-10-07 17:03:04 UTC (rev 1199) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/trace.c 2008-10-09 00:51:10 UTC (rev 1200) @@ -15,15 +15,17 @@ static HANDLE __wcetracehnd = NULL; static int __wcetrace = 0; static int __wcetrace_debugger = 0; /* Used to be WCE_ALL */ +static int __trace_closed = 0; void WCETRACESET(int trace) { - __wcetrace = trace; + if (!__trace_closed) + __wcetrace = trace; } int -WCETRACEGET() +WCETRACEGET(void) { return(__wcetrace); } @@ -35,7 +37,7 @@ } int -WCETRACE_DEBUGGER_GET() +WCETRACE_DEBUGGER_GET(void) { return(__wcetrace_debugger); } @@ -46,23 +48,75 @@ int flag; } trace_entry; +/* This define specifies how long a buffer is needed for displaying + all the levels. It should be the sum of all names of level + lengths, plus the amount of level lengths (for the separation + commas) plus 6 (currently) digits for displaying the numeric value + of the level. And then add a terminating 0, and a safety padding. + The WCE_ALL is not accounted for, as it consumes all other levels, + and never shows in the output. */ + +#define MAX_LEVEL_BUF (41 + 9 + 6 + 10) + static const trace_entry trace_entries[] = { { "all", WCE_ALL }, - { "io", WCE_IO }, - { "network", WCE_NETWORK }, - { "signals", WCE_SIGNALS }, - { "fifos", WCE_FIFOS }, - { "time", WCE_TIME }, - { "synch", WCE_SYNCH }, - { "malloc", WCE_MALLOC }, - { "vm", WCE_VM }, - { "app", WCE_APP }, - + { "io", WCE_IO }, /* 2 = 2 */ + { "network", WCE_NETWORK }, /* 7 = 9 */ + { "signals", WCE_SIGNALS }, /* 7 = 16 */ + { "fifos", WCE_FIFOS }, /* 5 = 21 */ + { "time", WCE_TIME }, /* 4 = 25 */ + { "synch", WCE_SYNCH }, /* 5 = 30 */ + { "malloc", WCE_MALLOC }, /* 6 = 36 */ + { "vm", WCE_VM }, /* 2 = 38 */ + { "app", WCE_APP }, /* 3 = 41 */ + { NULL, 0 } }; +/* Convert LEVEL into a comma separated string, and store it in TO. + TO must be at least MAX_LEVEL_BUF long. */ + +static void +get_level_name(int level, char *to) +{ + int virgin = 1; + + const trace_entry *ent = trace_entries + 1; + for (; ent->str; ent++) + { + if (level & ent->flag) + { + int len; + + level &= ~ent->flag; + if (!virgin) + *(to++) = ','; + else + virgin = 0; + + len = strlen(ent->str); + memcpy(to, ent->str, len); + to += len; + } + } + + if (level) + { + int printed; + + /* There were some unresolved flags. */ + if (!virgin) + *(to++) = ','; + + printed = sprintf(to, "%#04.4x", level); + to += printed; + } + + *to = 0; +} + void NKDbgPrintfA(const char *fmt, ...); static void set_from_env(const char* env, int* what) @@ -111,33 +165,44 @@ } void -WCETRACEGETENV() +WCETRACEGETENV(void) { set_from_env("WCETRACE", &__wcetrace); set_from_env("WCETRACE_DEBUGGER", &__wcetrace_debugger); } void -WCETRACECLOSE() +WCETRACECLOSE(void) { if (__wcetracehnd != NULL && __wcetracehnd != INVALID_HANDLE_VALUE) { + __wcetrace = WCE_IO; + __WCETrace(WCE_IO, "Trace file is being closed"); FlushFileBuffers(__wcetracehnd); XCECloseHandle(__wcetracehnd); __wcetracehnd = NULL; + __trace_closed = 1; + __wcetrace = 0; } } void -WCETRACE(int level, const char *fmt, ...) +__WCETrace(int level, const char *fmt, ...) { + int len; + char level_name[MAX_LEVEL_BUF]; + char buf[1024]; + + va_list ap; + if (!(__wcetrace_debugger & level) && !(__wcetrace & level)) return; - char buf[1024]; - int len = sprintf(buf, "%08X:%08X: ", GetTickCount(), GetCurrentThreadId()); + get_level_name(level, level_name); + len = sprintf(buf, "%08X:%08X: [%s] ", + GetTickCount(), GetCurrentThreadId(), + level_name); - va_list ap; va_start(ap, fmt); vsprintf(buf + len, fmt, ap); strcat(buf, "\n"); @@ -148,7 +213,7 @@ wchar_t tracepathw[256]; const char* tmppath = getenv("TMP"); int pid = getpid(); - NKDbgPrintfW(L"pid is %d (%x)", pid, pid); + NKDbgPrintfW(L"pid is %d (%x)\n", pid, pid); if (!tmppath || strlen(tmppath) == 0) sprintf(tracepath, "/Temp/wcetrace%u.log", pid); else @@ -181,23 +246,26 @@ } } -void __WCETraceError(int trace, DWORD error, const char* func) +void +__WCETraceError(int trace, DWORD error, const char* func) { wchar_t* wbuf; + int len; + char* buf; FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t*) &wbuf, - 0, NULL ); + 0, NULL); - int len = wcslen(wbuf); - char* buf = alloca(len); - wcstombs(buf, wbuf, len+1); + len = wcslen(wbuf); + buf = alloca(len + 1); + wcstombs(buf, wbuf, len + 1); LocalFree(wbuf); WCETRACE(trace, "%s failed with error %d: %s", func, (int)error, buf); printf("%s failed with error %d: %s\n", func, (int)error, buf); } -#endif // CE_NOTRACE +#endif /* CE_NOTRACE */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2009-04-28 14:06:06
|
Revision: 1258 http://cegcc.svn.sourceforge.net/cegcc/?rev=1258&view=rev Author: dannybackx Date: 2009-04-28 14:03:01 +0000 (Tue, 28 Apr 2009) Log Message: ----------- Ismail's fix for recognizing more versions. My addition (on my disk for ages) for the other architecture. Modified Paths: -------------- trunk/cegcc/src/newlib/ChangeLog.cegcc trunk/cegcc/src/newlib/configure trunk/cegcc/src/newlib/configure.in Modified: trunk/cegcc/src/newlib/ChangeLog.cegcc =================================================================== --- trunk/cegcc/src/newlib/ChangeLog.cegcc 2009-04-28 13:44:30 UTC (rev 1257) +++ trunk/cegcc/src/newlib/ChangeLog.cegcc 2009-04-28 14:03:01 UTC (rev 1258) @@ -1,3 +1,12 @@ +2009-04-28 Danny Backx <dan...@us...> + + * configure, configure.in : recognize more targets. + +2009-04-28 Ismail Khatib <ik...@im...> + + * configure, configure.in : Make it recognize newer versions of + texinfo (4.9 was recognized, 4.13 not). + 2008-10-09 Pawel Veselov <paw...@gm...> newlib/ Modified: trunk/cegcc/src/newlib/configure =================================================================== --- trunk/cegcc/src/newlib/configure 2009-04-28 13:44:30 UTC (rev 1257) +++ trunk/cegcc/src/newlib/configure 2009-04-28 14:03:01 UTC (rev 1258) @@ -2724,7 +2724,7 @@ # ranlib from Darwin requires the -c flag to look at common symbols. extra_ranlibflags_for_target=" -c" ;; - mips*-*-pe | sh*-*-pe | *arm-wince-pe | *arm-wince-cegcc) + mips*-*-pe | sh*-*-pe | arm-unknown-* | *arm-wince-pe | *arm-wince-cegcc) target_makefile_frag="config/mt-wince" ;; esac @@ -3543,7 +3543,7 @@ # For an installed makeinfo, we require it to be from texinfo 4.2 or # higher, else we use the "missing" dummy. if ${MAKEINFO} --version \ - | egrep 'texinfo[^0-9]*([1-3][0-9]|4\.[2-9]|[5-9])' >/dev/null 2>&1; then + | egrep 'texinfo[^0-9]*([1-3][0-9]|4\.)([2-9]|[1-9].*)' >/dev/null 2>&1; then : else MAKEINFO="$MISSING makeinfo" Modified: trunk/cegcc/src/newlib/configure.in =================================================================== --- trunk/cegcc/src/newlib/configure.in 2009-04-28 13:44:30 UTC (rev 1257) +++ trunk/cegcc/src/newlib/configure.in 2009-04-28 14:03:01 UTC (rev 1258) @@ -1519,7 +1519,7 @@ # ranlib from Darwin requires the -c flag to look at common symbols. extra_ranlibflags_for_target=" -c" ;; - mips*-*-pe | sh*-*-pe | *arm-wince-pe | *arm-wince-cegcc) + mips*-*-pe | sh*-*-pe | arm-unknown-* | *arm-wince-pe | *arm-wince-cegcc) target_makefile_frag="config/mt-wince" ;; esac @@ -2128,7 +2128,7 @@ # For an installed makeinfo, we require it to be from texinfo 4.2 or # higher, else we use the "missing" dummy. if ${MAKEINFO} --version \ - | egrep 'texinfo[^0-9]*([1-3][0-9]|4\.[2-9]|[5-9])' >/dev/null 2>&1; then + | egrep 'texinfo[^0-9]*([1-3][0-9]|4\.)([2-9]|[1-9].*)' >/dev/null 2>&1; then : else MAKEINFO="$MISSING makeinfo" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-01-02 06:04:10
|
Revision: 1430 http://cegcc.svn.sourceforge.net/cegcc/?rev=1430&view=rev Author: dannybackx Date: 2010-01-02 06:04:04 +0000 (Sat, 02 Jan 2010) Log Message: ----------- Fix bug 2912803 Modified Paths: -------------- trunk/cegcc/src/newlib/ChangeLog.cegcc trunk/cegcc/src/newlib/newlib/libc/sys/wince/cefixpath.c Modified: trunk/cegcc/src/newlib/ChangeLog.cegcc =================================================================== --- trunk/cegcc/src/newlib/ChangeLog.cegcc 2010-01-02 01:20:33 UTC (rev 1429) +++ trunk/cegcc/src/newlib/ChangeLog.cegcc 2010-01-02 06:04:04 UTC (rev 1430) @@ -1,3 +1,7 @@ +2010-01-02 Danny Backx <dan...@us...> + + * libc/sys/wince/cefixpath.c(XCEFixPathA): Fix for bug 2912803. + 2009-04-28 Danny Backx <dan...@us...> * configure, configure.in : recognize more targets. Modified: trunk/cegcc/src/newlib/newlib/libc/sys/wince/cefixpath.c =================================================================== --- trunk/cegcc/src/newlib/newlib/libc/sys/wince/cefixpath.c 2010-01-02 01:20:33 UTC (rev 1429) +++ trunk/cegcc/src/newlib/newlib/libc/sys/wince/cefixpath.c 2010-01-02 06:04:04 UTC (rev 1430) @@ -4,6 +4,7 @@ #define WIN32_LEAN_AND_MEAN #include <windows.h> +#include <locale.h> char *XCEFixPathA(const char *pathin, char *pathout); wchar_t *XCEFixPathW(const wchar_t *wpathin, wchar_t *wpathout); @@ -14,17 +15,18 @@ { wchar_t wpathin[MAX_PATH]; wchar_t wpathout[MAX_PATH]; + int old_locale; //printf("FixPathA: %s\n", pathin); - MultiByteToWideChar(CP_ACP, 0, pathin, -1, wpathin, MAX_PATH); + old_locale = setlocale(LC_ALL, "C"); + (void) setlocale(LC_ALL, old_locale); + MultiByteToWideChar(old_locale, 0, pathin, -1, wpathin, MAX_PATH); + XCEFixPathW(wpathin, wpathout); - WideCharToMultiByte(CP_ACP, 0, - wpathout, -1, - pathout, MAX_PATH, - NULL, NULL); + WideCharToMultiByte(old_locale, 0, wpathout, -1, pathout, MAX_PATH, NULL, NULL); return pathout; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |