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. |