1
0
mirror of https://github.com/adtools/clib2.git synced 2025-12-08 14:59:05 +00:00

- Added atoll(), ffs(), ftw(), nftw(), lstat() and uname() code

contributed by Peter Bengtsson. Thank you very much!


git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14848 87f5fb63-7c3d-0410-a384-fd976d0f7a62
This commit is contained in:
Olaf Barthel
2005-03-02 12:57:56 +00:00
parent ef44c75126
commit ac0cc97924
15 changed files with 1395 additions and 19 deletions

View File

@ -1,5 +1,5 @@
#
# $Id: GNUmakefile.68k,v 1.32 2005-02-28 13:22:53 obarthel Exp $
# $Id: GNUmakefile.68k,v 1.33 2005-03-02 12:57:53 obarthel Exp $
#
# :ts=8
#
@ -148,6 +148,8 @@ C_LIB = \
fcntl_open.o \
fcntl_read.o \
fcntl_write.o \
ftw_ftw.o \
ftw_nftw.o \
libgen_basename.o \
libgen_dirname.o \
locale_init_exit.o \
@ -269,6 +271,7 @@ C_LIB = \
stdlib_atexit.o \
stdlib_atoi.o \
stdlib_atol.o \
stdlib_atoll.o \
stdlib_bsearch.o \
stdlib_calloc.o \
stdlib_checkdetach.o \
@ -344,6 +347,7 @@ C_LIB = \
stdlib_umodsi3.o \
stdlib_unsetenv.o \
stdlib_wildcard_expand.o \
strings_ffs.o \
strings_strcasecmp.o \
strings_strncasecmp.o \
string_bcmp.o \
@ -427,7 +431,8 @@ C_LIB = \
unistd_truncate.o \
unistd_unlink.o \
unistd_usleep.o \
utime_utime.o
utime_utime.o \
utsname_uname.o
UNIX_LIB = \
unix.lib_rev.o \
@ -653,7 +658,8 @@ NET_LIB = \
usergroup_setregid.o \
usergroup_setreuid.o \
usergroup_setsid.o \
usergroup_setuid.o
usergroup_setuid.o \
utsname_uname.o
DEBUG_LIB = \
debug.lib_rev.o \

View File

@ -1,5 +1,5 @@
#
# $Id: GNUmakefile.os4,v 1.32 2005-02-28 13:22:53 obarthel Exp $
# $Id: GNUmakefile.os4,v 1.33 2005-03-02 12:57:53 obarthel Exp $
#
# :ts=8
#
@ -152,6 +152,8 @@ C_LIB = \
fcntl_open.o \
fcntl_read.o \
fcntl_write.o \
ftw_ftw.o \
ftw_nftw.o \
libgen_basename.o \
libgen_dirname.o \
locale_init_exit.o \
@ -273,6 +275,7 @@ C_LIB = \
stdlib_atexit.o \
stdlib_atoi.o \
stdlib_atol.o \
stdlib_atoll.o \
stdlib_bsearch.o \
stdlib_calloc.o \
stdlib_checkdetach.o \
@ -348,6 +351,7 @@ C_LIB = \
stdlib_umodsi3.o \
stdlib_unsetenv.o \
stdlib_wildcard_expand.o \
strings_ffs.o \
strings_strcasecmp.o \
strings_strncasecmp.o \
string_bcmp.o \
@ -431,7 +435,8 @@ C_LIB = \
unistd_truncate.o \
unistd_unlink.o \
unistd_usleep.o \
utime_utime.o
utime_utime.o \
utsname_uname.o
# All objects files which make up libunix.a
UNIX_LIB = \
@ -620,7 +625,8 @@ NET_LIB = \
usergroup_setregid.o \
usergroup_setreuid.o \
usergroup_setsid.o \
usergroup_setuid.o
usergroup_setuid.o \
utsname_uname.o
# All objects files which make up libdebug.a
DEBUG_LIB = \

View File

@ -80,6 +80,9 @@
absolute Amiga path names passed to it and will use them without
changing them.
- Added atoll(), ffs(), ftw(), nftw(), lstat() and uname() code
contributed by Peter Bengtsson. Thank you very much!
c.lib 1.188 (7.2.2005)

238
library/ftw_ftw.c Normal file
View File

@ -0,0 +1,238 @@
/*
* $Id: ftw_ftw.c,v 1.1 2005-03-02 12:57:53 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/****************************************************************************/
/* The following is not part of the ISO 'C' (1994) standard. */
/****************************************************************************/
/*
* This ftw() implementation builds heavily on existing functionality and could certainly
* be made more efficient (e.g. by combining walk & stat using ExAll()/ExNext()) but this
* way the Unix pathname translation is free.
*/
/****************************************************************************/
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <ftw.h>
#include <errno.h>
/****************************************************************************/
#ifndef _DEBUG_H
#include "debug.h"
#endif /* _DEBUG_H */
#ifndef _FTW_HEADERS_H
#include "ftw_headers.h"
#endif /* _FTW_HEADERS_H */
#ifndef _STDLIB_PROTOS_H
#include "stdlib_protos.h" /* get/set errno. */
#endif /* _STDLIB_PROTOS_H */
/****************************************************************************/
static int
walk(const char *path,int (*func)(const char *,const struct stat *,int),int depth,int level)
{
int result = 0;
DIR *dp;
struct dirent *de;
struct stat st;
char *next_name;
int type;
int old_length;
int errtmp;
ENTER();
SHOWSTRING(path);
SHOWPOINTER(func);
SHOWVALUE(depth);
SHOWVALUE(level);
if(__check_abort_enabled)
__check_abort();
if(level > depth)
goto out;
if(stat(path,&st) == OK)
{
if (S_ISDIR(st.st_mode))
{
if(FLAG_IS_SET(st.st_mode,S_IRUSR))
type = FTW_D; /* Directory */
else
type = FTW_DNR; /* Directory No Read-permission */
}
else if (S_ISREG(st.st_mode))
{
type = FTW_F; /* File */
}
else
{
/* Skip */
goto out;
}
}
else
{
type = FTW_NS; /* No Stat */
}
result = (*func)(path,&st,type);
if(result != 0)
goto out;
if(type == FTW_D)
{
dp = opendir(path); /* Also takes care of Unix->Amiga pathname conversion. */
if(dp == NULL)
{
result = -1; /* Pass errno from opendir() */
goto out;
}
old_length = strlen(path);
next_name = malloc(old_length + NAME_MAX + 2); /* Allocate new for each recursive step to handle extremely long path names. */
if(next_name == NULL)
{
__set_errno(ENOMEM);
result = -1;
goto out;
}
strcpy(next_name,path);
if(old_length > 0 && next_name[old_length - 1] != ':' && next_name[old_length-1] != '/')
next_name[old_length++] = '/';
while((result == 0) && (de = readdir(dp)) != NULL)
{
strlcpy(&next_name[old_length],de->d_name,NAME_MAX + 2);
result = walk(next_name,func,depth,level+1);
}
errtmp = __get_errno();
closedir(dp);
free(next_name);
__set_errno(errtmp);
}
out:
RETURN(result);
return(result);
}
int
ftw(const char *path,int (*func)(const char *,const struct stat *,int),int depth)
{
int result = -1;
char *base;
int len;
ENTER();
SHOWSTRING(path);
SHOWPOINTER(func);
SHOWVALUE(depth);
if(path == NULL)
{
SHOWMSG("NULL pathname to ftw().");
__set_errno(EFAULT);
goto out;
}
if(func == NULL)
{
SHOWMSG("No function supplied.");
__set_errno(EFAULT);
goto out;
}
if(depth < 0)
{
SHOWMSG("Invalid depth.\n");
__set_errno(EINVAL);
goto out;
}
/* Make sure the path never ends with '/' unless used to indicate parent directory. */
len = strlen(path);
if(len > 1 && path[len - 1] == '/' && path[len - 2] != '/')
{
int error;
base = strdup(path);
if(base == NULL)
{
__set_errno(ENOMEM);
goto out;
}
base[len - 1] = '\0';
result = walk(base,func,depth,0);
error = __get_errno();
free(base);
__set_errno(error);
}
else
{
result = walk(path,func,depth,0);
}
out:
RETURN(result);
return(result);
}

47
library/ftw_headers.h Normal file
View File

@ -0,0 +1,47 @@
/*
* $Id: ftw_headers.h,v 1.1 2005-03-02 12:57:53 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FTW_HEADERS_H
#define _FTW_HEADERS_H
/****************************************************************************/
#include <sys/stat.h>
/****************************************************************************/
#include "macros.h"
/****************************************************************************/
#endif /* _FTW_HEADERS_H */

334
library/ftw_nftw.c Normal file
View File

@ -0,0 +1,334 @@
/*
* $Id: ftw_nftw.c,v 1.1 2005-03-02 12:57:53 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/****************************************************************************/
/* The following is not part of the ISO 'C' (1994) standard. */
/****************************************************************************/
/*
* This nftw() implementation builds heavily on existing functionality and could certainly
* be made more efficient.
*/
/****************************************************************************/
#include <dirent.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <ftw.h>
#include <errno.h>
/****************************************************************************/
#ifndef _DEBUG_H
#include "debug.h"
#endif /* _DEBUG_H */
#ifndef _FTW_HEADERS_H
#include "ftw_headers.h"
#endif /* _FTW_HEADERS_H */
#ifndef _STDLIB_PROTOS_H
#include "stdlib_protos.h" /* get/set errno. */
#endif /* _STDLIB_PROTOS_H */
/****************************************************************************/
static int
walk(const char *path,int (*func)(const char *,const struct stat *,int,struct FTW *),const int depth,int level,const int flags,const int base,int * const prune)
{
int result = 0;
DIR *dp;
struct dirent *de;
struct stat st;
char *next_name;
char *old_cwd = 0;
int type;
int old_length;
int errtmp;
struct FTW extra_info;
int stat_result;
ENTER();
SHOWSTRING(path);
SHOWPOINTER(func);
SHOWVALUE(depth);
SHOWVALUE(level);
SHOWVALUE(flags);
if(__check_abort_enabled)
__check_abort();
if(level > depth)
goto out;
if(FLAG_IS_SET(flags,FTW_PHYS))
stat_result = lstat(path,&st);
else
stat_result = stat(path,&st);
if(stat_result == OK)
{
if (S_ISLNK(st.st_mode)) /* Should only be possible if lstat() is used. */
{
type = FTW_SL;
}
else if (S_ISDIR(st.st_mode))
{
if(FLAG_IS_SET(st.st_mode,S_IRUSR))
type = FTW_D; /* Directory */
else
type = FTW_DNR; /* Directory No Read-permission */
}
else if (S_ISREG(st.st_mode))
{
type = FTW_F; /* File */
}
else
{
/* Skip */
goto out;
}
}
else
{
if(FLAG_IS_CLEAR(flags,FTW_PHYS) && lstat(path,&st) == OK)
type = FTW_SLN; /* Broken link. */
else
type = FTW_NS; /* No Stat */
}
extra_info.quit = 0;
extra_info.base = base;
extra_info.level = level;
if(type == FTW_D)
{
old_length = strlen(path);
if(FLAG_IS_CLEAR(flags,FTW_DEPTH))
result = (*func)(path,&st,type,&extra_info);
if(extra_info.quit == 0)
{
dp = opendir(path); /* Also takes care of Unix->Amiga pathname conversion. */
if(dp == NULL)
{
result = -1;
goto out;
}
if(FLAG_IS_SET(flags,FTW_CHDIR)) /* Change to directory before traversing. */
{
old_cwd = malloc(old_length + NAME_MAX);
if(old_cwd == NULL)
{
__set_errno(ENOMEM);
result = -1;
goto out;
}
getcwd(old_cwd,old_length + NAME_MAX);
chdir(path);
}
next_name = malloc(old_length + NAME_MAX + 2); /* Allocate new for each recursive step to handle extremely long path names. */
if(next_name == NULL)
{
__set_errno(ENOMEM);
result = -1;
goto out;
}
strcpy(next_name,path);
if(old_length > 0 && next_name[old_length - 1] != ':' && next_name[old_length - 1] != '/')
next_name[old_length++] = '/';
while((result == 0) && (de = readdir(dp)) != NULL)
{
strlcpy(&next_name[old_length],de->d_name,NAME_MAX + 2);
result = walk(next_name,func,depth,level + 1,flags,old_length,prune);
if((*prune) != 0)
{
(*prune) = 0;
break;
}
}
errtmp = __get_errno();
closedir(dp);
__set_errno(errtmp);
free(next_name);
if((result == 0) && FLAG_IS_SET(flags,FTW_DEPTH))
result = (*func)(path,&st,FTW_DP,&extra_info);
}
if(extra_info.quit == FTW_PRUNE) /* Abort traversal of current directory. */
(*prune) = 1;
}
else
{
result = (*func)(path,&st,type,&extra_info);
}
out:
if(old_cwd != NULL)
{
errtmp = __get_errno();
chdir(old_cwd); /* Restore (pop) old directory. */
free(old_cwd);
__set_errno(errtmp);
}
RETURN(result);
return(result);
}
/****************************************************************/
static int
index_of_end_part(const char *path)
{
int result = 0;
int i;
i = strlen(path) - 1;
while(i-- > 0)
{
if(path[i] == '/' || path[i] == ':')
{
result = i + 1;
break;
}
}
return(result);
}
/****************************************************************/
int
nftw(const char *path,int (*func)(const char *,const struct stat *,int,struct FTW *),int depth,int flags)
{
char *base;
int len;
int base_index;
int prune = 0;
int result = -1;
ENTER();
SHOWSTRING(path);
SHOWPOINTER(func);
SHOWVALUE(depth);
SHOWVALUE(flags);
if(path == NULL)
{
SHOWMSG("NULL pathname to nftw().");
__set_errno(EFAULT);
goto out;
}
if(func == NULL)
{
SHOWMSG("No function supplied.");
__set_errno(EFAULT);
goto out;
}
if(depth < 0)
{
SHOWMSG("Invalid depth.\n");
__set_errno(EINVAL);
goto out;
}
if((flags & ~FTW_ALL_FLAGS) != 0)
{
SHOWMSG("Bogus flags.");
__set_errno(EINVAL);
goto out;
}
/* Make sure the path never ends with '/' unless used to indicate parent directory. */
len = strlen(path);
if(len > 1 && path[len - 1] == '/' && path[len - 2] != '/')
{
int error;
base = strdup(path);
if(base == NULL)
{
__set_errno(ENOMEM);
goto out;
}
base[len - 1] = '\0';
base_index = index_of_end_part(base);
result = walk(base,func,depth,0,flags,base_index,&prune);
error = __get_errno();
free(base);
__set_errno(error);
}
else
{
base_index = index_of_end_part(path);
result = walk(path,func,depth,0,flags,base_index,&prune);
}
out:
RETURN(result);
return(result);
}

102
library/include/ftw.h Normal file
View File

@ -0,0 +1,102 @@
/*
* $Id: ftw.h,v 1.1 2005-03-02 12:57:56 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FTW_H
#define _FTW_H
/****************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/****************************************************************************/
/* The following is not part of the ISO 'C' (1994) standard. */
/****************************************************************************/
#include <sys/stat.h>
/****************************************************************************/
/* Values passed to the user function (argument #3). */
enum
{
FTW_F, /* Regular file. */
FTW_D, /* Directory. */
FTW_DP, /* Directory, already visited. (nftw() only) */
FTW_SL, /* Symlink. (nftw() only) */
FTW_SLN, /* Broken Symlink. (does not point to an existing file, nftw() only) */
FTW_DNR, /* Directory which can not be read (e.g. not enough permissions) */
FTW_NS /* Stat failed. */
};
/****************************************************************************/
/* Flags for FTW.quit */
#define FTW_SKD (1L<<0) /* Skip directory. */
#define FTW_PRUNE (1L<<1) /* Prune traversal. (skip up) */
/****************************************************************************/
/* Flags for nftw() */
#define FTW_PHYS (1L<<0)
#define FTW_MOUNT (1L<<1) /* Currently unsupported. */
#define FTW_DEPTH (1L<<2)
#define FTW_CHDIR (1L<<3)
#define FTW_ALL_FLAGS (0x0000000f)
/****************************************************************************/
struct FTW
{
int quit; /* Flags passed out from the user function to ftw()/nftw() */
int base; /* Index of current item from start of string. e.g. 4 for "foo/bar" */
int level; /* Current depth. (counted from 0) */
};
/****************************************************************************/
extern int ftw(const char *path,int (*func)(const char *,const struct stat *,int),int depth);
extern int nftw(const char *path,int (*func)(const char *,const struct stat *,int,struct FTW *),int depth,int flags);
/****************************************************************************/
#ifdef __cplusplus
}
#endif /* __cplusplus */
/****************************************************************************/
#endif /* _FTW_H */

View File

@ -1,5 +1,5 @@
/*
* $Id: stdlib.h,v 1.7 2005-02-27 18:09:12 obarthel Exp $
* $Id: stdlib.h,v 1.8 2005-03-02 12:57:56 obarthel Exp $
*
* :ts=4
*
@ -153,11 +153,12 @@ extern int rand_r(unsigned int * seed);
/****************************************************************************/
/* These two functions are unavailable under SAS/C for lack of a
/* These functions are unavailable under SAS/C for lack of a
"long long" data type. */
#if ! defined(__SASC)
extern long long strtoll(const char *str, char **ptr, int base);
extern unsigned long long strtoull(const char *str, char **ptr, int base);
extern long long atoll(const char *str);
#endif /* __SASC */
/****************************************************************************/

View File

@ -1,5 +1,5 @@
/*
* $Id: strings.h,v 1.3 2005-01-02 09:07:21 obarthel Exp $
* $Id: strings.h,v 1.4 2005-03-02 12:57:56 obarthel Exp $
*
* :ts=4
*
@ -52,9 +52,10 @@ extern "C" {
/****************************************************************************/
/* These two come from 4.4BSD. */
/* These come from 4.4BSD. */
extern int strcasecmp(const char *s1, const char *s2);
extern int strncasecmp(const char *s1, const char *s2, size_t len);
extern int ffs(int i);
/****************************************************************************/

View File

@ -0,0 +1,74 @@
/*
* $Id: utsname.h,v 1.1 2005-03-02 12:57:56 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SYS_UTSNAME_H
#define _SYS_UTSNAME_H
/****************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/****************************************************************************/
/* The following is not part of the ISO 'C' (1994) standard. */
/****************************************************************************/
#define SYS_NMLN 32
/****************************************************************************/
struct utsname
{
char sysname[SYS_NMLN]; /* OS Name ("AmigaOS") */
char nodename[SYS_NMLN]; /* Usually Hostname, but there appears to be no standard. */
char release[SYS_NMLN]; /* Release e.g. "51.1" (The Version of version.library) */
char version[SYS_NMLN]; /* Version e.h. "4.0" (OS Version) */
char machine[SYS_NMLN]; /* Machine e.g. "m68k" or "ppc" */
};
/****************************************************************************/
extern int uname(struct utsname *);
/****************************************************************************/
#ifdef __cplusplus
}
#endif /* __cplusplus */
/****************************************************************************/
#endif /* _SYS_UTSNAME_H */

View File

@ -1,5 +1,5 @@
_#
# $Id: smakefile,v 1.26 2005-02-28 13:22:53 obarthel Exp $
# $Id: smakefile,v 1.27 2005-03-02 12:57:53 obarthel Exp $
#
# :ts=8
#
@ -380,6 +380,7 @@ STDLIB_OBJ = \
stdlib_atof.o \
stdlib_atoi.o \
stdlib_atol.o \
stdlib_atoll.o \
stdlib_bsearch.o \
stdlib_calloc.o \
stdlib_checkdetach.o \
@ -483,6 +484,7 @@ STRING_OBJ = \
string_strxfrm.o
STRINGS_OBJ = \
strings_ffs.o \
strings_strcasecmp.o \
strings_strncasecmp.o
@ -510,6 +512,8 @@ TIME_OBJ = \
time_weekday.o
UNISTD_OBJ = \
ftw_ftw.o \
ftw_nftw.o \
unistd_access.o \
unistd_chdir.o \
unistd_chdir_exit.o \
@ -546,7 +550,8 @@ UNISTD_OBJ = \
unistd_truncate.o \
unistd_unix_path_semantics.o \
unistd_unlink.o \
unistd_usleep.o
unistd_usleep.o \
utsname_uname.o
# \
# unistd_wildcard_expand.o

View File

@ -1,5 +1,5 @@
/*
* $Id: stat_lstat.c,v 1.5 2005-02-28 10:07:30 obarthel Exp $
* $Id: stat_lstat.c,v 1.6 2005-03-02 12:57:53 obarthel Exp $
*
* :ts=4
*
@ -41,30 +41,174 @@
#include "stat_headers.h"
#endif /* _STAT_HEADERS_H */
#ifndef _LOCALE_HEADERS_H
#include "locale_headers.h"
#endif /* _LOCALE_HEADERS_H */
#ifndef _TIME_HEADERS_H
#include "time_headers.h"
#endif /* _TIME_HEADERS_H */
/****************************************************************************/
/* The following is not part of the ISO 'C' (1994) standard. */
/****************************************************************************/
int
lstat(const char * path_name, struct stat * buffer)
/*
* lstat_lock(): An implementation of Lock() which remembers whether or
* not it resolved soft links.
*
* Unfortunately is is limited to 255 character names.
*/
static BPTR
lstat_lock(const char *name,const int mode,int *link_length)
{
D_S(struct bcpl_name,bname);
const size_t name_size = sizeof(bname->name);
char * new_name = NULL;
struct DevProc * dvp = NULL;
LONG link_count = 16;
BPTR lock = ZERO;
size_t name_len;
LONG error;
name_len = strlen(name);
if(name_len >= name_size)
{
SetIoErr(ERROR_LINE_TOO_LONG);
goto out;
}
/* Convert the name into a BCPL string. */
bname->name[0] = name_len;
memmove(&bname->name[1],name,name_len);
while(TRUE)
{
/* Get a handle on the device, volume or assignment name in the path. */
dvp = GetDeviceProc(name,dvp);
if(dvp == NULL)
goto out;
/* Try to obtain a lock on the object. */
lock = DoPkt(dvp->dvp_Port,ACTION_LOCATE_OBJECT,dvp->dvp_Lock,MKBADDR(bname),mode,0,0);
if(lock != ZERO)
break;
error = IoErr();
if(error == ERROR_OBJECT_NOT_FOUND)
{
/* If this is part of a multi-volume assignment, try the next part. */
if(FLAG_IS_SET(dvp->dvp_Flags,DVPF_ASSIGN))
continue;
/* Not much we can do here... */
break;
}
else if (error == ERROR_IS_SOFT_LINK)
{
LONG result;
/* Should we give the soft link resolution another try? */
link_count--;
if(link_count == 0)
{
/* Nope, we already spent too much time trying to
resolve nested links. */
SetIoErr(ERROR_TOO_MANY_LEVELS);
goto out;
}
/* For soft link resolution we need a temporary buffer to
let the file system store the resolved path name in. */
if(new_name == NULL)
{
new_name = malloc(name_size);
if(new_name == NULL)
{
SetIoErr(ERROR_NO_FREE_STORE);
goto out;
}
strcpy(new_name,name);
name = new_name;
}
/* Now ask the file system to resolve the entire path. */
result = ReadLink(dvp->dvp_Port,dvp->dvp_Lock,name,name,name_size);
if(result < 0)
{
/* This will return either -1 (resolution error) or -2
(buffer too small). We regard both as trouble. */
SetIoErr(ERROR_INVALID_COMPONENT_NAME);
goto out;
}
/* Remember the length of the link name. */
if(result > 0)
(*link_length) = result;
/* We now have a new name to resolve. */
name_len = strlen(name);
bname->name[0] = name_len;
memmove(&bname->name[1],name,name_len);
}
else
{
/* Some other error; ask if the user wants to have another go at it. */
if(ErrorReport(error,REPORT_LOCK,dvp->dvp_Lock,dp->dvp_Port) != 0)
break;
}
/* Retry the lookup. */
FreeDeviceProc(dvp);
dvp = NULL;
}
out:
error = IoErr();
if(new_name != NULL)
free(new_name);
FreeDeviceProc(dvp);
SetIoErr(error);
return(lock);
}
int
lstat(const char * path_name, struct stat * st)
{
#if defined(UNIX_PATH_SEMANTICS)
struct name_translation_info path_name_nti;
#endif /* UNIX_PATH_SEMANTICS */
D_S(struct FileInfoBlock,fib);
struct FileLock * fl;
int result = -1;
LONG status;
BPTR file_lock = ZERO;
int link_length = 0;
ENTER();
SHOWSTRING(path_name);
SHOWPOINTER(buffer);
SHOWPOINTER(st);
assert( path_name != NULL && buffer != NULL );
assert( path_name != NULL && st != NULL );
if(__check_abort_enabled)
__check_abort();
#if defined(CHECK_FOR_NULL_POINTERS)
{
if(path_name == NULL || buffer == NULL)
if(path_name == NULL || st == NULL)
{
SHOWMSG("invalid parameters");
@ -74,10 +218,110 @@ lstat(const char * path_name, struct stat * buffer)
}
#endif /* CHECK_FOR_NULL_POINTERS */
result = stat(path_name,buffer);
#if defined(UNIX_PATH_SEMANTICS)
{
if(__unix_path_semantics)
{
if(__translate_unix_to_amiga_path_name(&path_name,&path_name_nti) != 0)
goto out;
/* The pseudo root directory is a very special case indeed.
We make up some pseudo data for it. */
if(path_name_nti.is_root)
{
struct DateStamp ds;
time_t mtime;
SHOWMSG("setting up the root directory info");
memset(st,0,sizeof(*st));
PROFILE_OFF();
DateStamp(&ds);
PROFILE_ON();
mtime = __convert_datestamp_to_time(&ds);
st->st_mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
st->st_mtime = mtime;
st->st_atime = mtime;
st->st_ctime = mtime;
st->st_nlink = 2;
st->st_blksize = 512;
result = 0;
goto out;
}
}
}
#endif /* UNIX_PATH_SEMANTICS */
D(("trying to get a lock on '%s'",path_name));
PROFILE_OFF();
file_lock = lstat_lock(path_name,SHARED_LOCK,&link_length);
PROFILE_ON();
if(file_lock == ZERO)
{
SHOWMSG("that didn't work");
__set_errno(__translate_access_io_error_to_errno(IoErr()));
goto out;
}
if(link_length > 0)
{
struct DateStamp ds;
time_t mtime;
/* Build a dummy stat for the link. */
SHOWMSG("Creating stat info for link.");
memset(st,0,sizeof(*st));
PROFILE_OFF();
DateStamp(&ds);
PROFILE_ON();
mtime = __convert_datestamp_to_time(&ds);
st->st_mode = S_IFLNK | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
st->st_dev = DeviceProc(path_name);
st->st_size = link_length;
st->st_mtime = mtime;
st->st_atime = mtime;
st->st_ctime = mtime;
st->st_nlink = 1;
}
else
{
PROFILE_OFF();
status = Examine(file_lock,fib);
PROFILE_ON();
if(status == DOSFALSE)
{
SHOWMSG("couldn't examine it");
__set_errno(__translate_io_error_to_errno(IoErr()));
goto out;
}
fl = BADDR(file_lock);
__convert_file_info_to_stat(fl->fl_Task,fib,st);
}
result = 0;
out:
PROFILE_OFF();
UnLock(file_lock);
PROFILE_ON();
RETURN(result);
return(result);
}

76
library/stdlib_atoll.c Normal file
View File

@ -0,0 +1,76 @@
/*
* $Id: stdlib_atoll.c,v 1.1 2005-03-02 12:57:53 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STDLIB_NULL_POINTER_CHECK_H
#include "stdlib_null_pointer_check.h"
#endif /* _STDLIB_NULL_POINTER_CHECK_H */
/****************************************************************************/
#ifndef _STDLIB_HEADERS_H
#include "stdlib_headers.h"
#endif /* _STDLIB_HEADERS_H */
/****************************************************************************/
#if defined(USE_64_BIT_INTS)
/****************************************************************************/
long long
atoll(const char *str)
{
long long result = 0;
assert( str != NULL );
#if defined(CHECK_FOR_NULL_POINTERS)
{
if(str == NULL)
{
errno = EFAULT;
goto out;
}
}
#endif /* CHECK_FOR_NULL_POINTERS */
result = strtoll(str, (char **)NULL, 10);
out:
return(result);
}
/****************************************************************************/
#endif /* USE_64_BIT_INTS */

71
library/strings_ffs.c Normal file
View File

@ -0,0 +1,71 @@
/*
* $Id: strings_ffs.c,v 1.1 2005-03-02 12:57:53 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STDLIB_NULL_POINTER_CHECK_H
#include "stdlib_null_pointer_check.h"
#endif /* _STDLIB_NULL_POINTER_CHECK_H */
/****************************************************************************/
#ifndef _STRINGS_HEADERS_H
#include "strings_headers.h"
#endif /* _STRINGS_HEADERS_H */
/****************************************************************************/
/* The following is not part of the ISO 'C' (1994) standard. */
/****************************************************************************/
/* Return the index of the lowest set bit. (Counted from one) */
int
ffs(int i)
{
int result = 0;
if(i != 0)
{
int x;
x = (i & (-i)) - 1;
x -= ((x >> 1) & 0x55555555);
x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
x = ((x >> 4) + x) & 0x0f0f0f0f;
x += (x >> 8);
x += (x >> 16);
result = 1 + (x & 0x3f); /* The first bit has index 1. */
}
return(result);
}

168
library/utsname_uname.c Normal file
View File

@ -0,0 +1,168 @@
/*
* $Id: utsname_uname.c,v 1.1 2005-03-02 12:57:53 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/****************************************************************************/
/* The following is not part of the ISO 'C' (1994) standard. */
/****************************************************************************/
#include <sys/utsname.h>
/****************************************************************************/
#if defined(SOCKET_SUPPORT) && !defined(_SOCKET_HEADERS_H)
#include "socket_headers.h"
#endif /* SOCKET_SUPPORT && !_SOCKET_HEADERS_H */
#ifndef _STDLIB_HEADERS_H
#include "stdlib_headers.h"
#endif /* _STDLIB_HEADERS_H */
#ifndef _DEBUG_H
#include "debug.h"
#endif /* _DEBUG_H */
/****************************************************************************/
#define OSNAME "AmigaOS"
/****************************************************************************/
#ifdef __amigaos4__
#define ARCH "ppc"
#else
#define ARCH "m68k" /* XXX: How should Coldfire accelerators be handled? */
#endif /* __amigaos4__ */
/****************************************************************************/
int
uname(struct utsname *info)
{
struct Library * VersionBase;
int Version,Revision;
char * version_string;
int result = -1;
ENTER();
SHOWPOINTER(info);
if(info == NULL)
{
__set_errno(EFAULT);
goto out;
}
strlcpy(info->sysname,OSNAME,sizeof(info->sysname));
#if defined(SOCKET_SUPPORT)
__gethostname((STRPTR)info->nodename,sizeof(info->nodename));
#else
strlcpy(info->nodename,"localhost",sizeof(info->nodename));
#endif /* SOCKET_SUPPORT */
VersionBase = OpenLibrary("version.library",0L);
if(VersionBase != NULL)
{
Version = VersionBase->lib_Version;
Revision = VersionBase->lib_Revision;
CloseLibrary(VersionBase);
}
else
{
Version = 0;
Revision = 0;
}
snprintf(info->release,sizeof(info->release),"%d.%d",Version,Revision);
/* This is mostly a stab in the dark. Is there any "official" way of finding out the OS version?
* Also, this could be more detailed e.g. "3.9-BB2" instead of just "3.9".
* For the curious:
*
* V.R OS Version
*
* 30.x 1.0 (Never released)
* 31.x 1.1 (NTSC)
* 32.x 1.1 (PAL)
* 33.x 1.2
* 34.x 1.3
* 35.x 1.3 (with A2024 support)
* 36.x 2.0-2.02
* 37.x 2.04-2.05
* 38.x 2.1
* 39.x 3.0
* 40.x 3.1
* 43.x 3.2 (Never released)
* 44.2 3.5
* 44.4 3.5-BB1
* 44.5 3.5-BB2
* 45.1 3.9
* 45.2 3.9-BB1
* 45.3 3.9-BB2
*
*/
if (Version >= 46)
version_string = "4.0";
else if (Version == 45)
version_string = "3.9";
else if (Version >= 44)
version_string = "3.5";
else if (Version >= 40)
version_string = 3.1";
else if (Version >= 39)
version_string = "3.0";
else
version_string = "unknown";
strlcpy(info->version,version_string,sizeof(info->version));
strlcpy(info->machine,ARCH,sizeof(info->machine));
SHOWSTRING(info->sysname);
SHOWSTRING(info->nodename);
SHOWSTRING(info->release);
SHOWSTRING(info->version);
SHOWSTRING(info->machine);
result = 0;
out:
RETURN(result);
return(result);
}