Merge pull request #89 from MBeijer/feature/strlcpy

Add strlcpy
This commit is contained in:
Stefan "Bebbo" Franke 2024-09-22 16:03:31 +02:00 committed by GitHub
commit 1fa1c6f953
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 108 additions and 1 deletions

View File

@ -71,6 +71,7 @@ __stdargs size_t strlen_plus_one(const char *string);
__stdargs char *strcpy(char *, const char *);
__stdargs char *strlwr(char *s);
__stdargs char *stpcpy(char *dst, const char *src);
__stdargs size_t strlcpy(char *dst, const char *src, size_t dsize);
__stdargs void *mempcpy(void *, const void *, size_t);
#else
#include "strsup.h"

View File

@ -13,7 +13,6 @@ int remove(const char *filename)
if((filename=__amigapath(filename))==NULL)
return -1;
#endif
puts(filename);
if(DeleteFile((CONST_STRPTR)filename))
return 0;
else

View File

@ -0,0 +1,18 @@
#include <ctype.h>
#include <string.h>
size_t strlcpy(char *dst, const char *src, size_t dsize) {
const char * p = src;
if (dsize) {
while (dsize--) {
if ((*dst++ = *p++) == 0)
break;
}
dst[-1] = 0;
}
while (*p)
++p;
return p - src;
}

View File

@ -0,0 +1,89 @@
# include <errno.h>
# include <stdint.h>
# include <stdlib.h>
# include <proto/dos.h>
/* getcwd() for Kickstart 1.3 that attempts to follow POSIX spec
* Features:
* - error checking, no extra allocations, no recursion, O(n)
*
* We start from the current directory and walk up to the root.
* Imagine we are in MyPath:MyDir/MySubDir
* We obtain a FileInfoBlock to MySubDir, then MyDir then MyPath.
* To avoid allocating extra stuff, holding multiple locks, recursing, etc.
* we write out all the names as we encounter them in reverse.
* Example:
* - obtain a lock to MySubDir, write out riDbuSyM
* - obtain a lock to MyDir, append /riDyM
* - obtain a lock to MyPath, append :htaPyM
* Now we have: riDbuSyM/riDyM:htaPyM
* then we reverse the string at the end:
* MyPath:MyDir/MySubDir
* This requires no extra memory bookkeeping or recursion.
*/
char *getcwd(char *buf, size_t size) {
if (!size) return errno = EINVAL, NULL;
char *mybuf = NULL;
if (!buf && !(mybuf = buf = (char *) malloc(size)))
return errno = ENOMEM, NULL;
BPTR dirlock = Lock("", ACCESS_READ);
if (!dirlock) { errno = ENOENT; goto fail; }
char *out = buf;
*out = 0;
size_t out_size = 0;
do {
struct FileInfoBlock fib;
if (!Examine(dirlock, &fib)) { errno = EIO; goto fail; }
{
BPTR new_dirlock = ParentDir(dirlock);
UnLock(dirlock);
dirlock = new_dirlock;
}
/* Prepend '/' to path except in following cases:
- if dirlock is 0, we are at the last element (root directory)
- if out_size is 0, we are at the first element */
if (out_size && dirlock) *out++ = '/';
/* Walk a pointer endname to the end of the file name */
char *name = fib.fib_FileName, *endname = name;
while (*endname++) {}
uint16_t name_len = --endname - name;
/* Some environments (vamos) will already have ':' added to the root dir */
const int needs_colon = !dirlock && (!name_len || endname[-1] != ':');
/* Determine if we have enough space to store the path */
out_size += name_len + needs_colon;
if (out_size >= size) { errno = ERANGE; goto fail; }
if (needs_colon)
*out++ = ':';
/* Write out the path component in reverse */
while (name_len--)
*out++ = *--endname;
} while (dirlock);
/* Terminate the string */
*out = 0;
/* Reverse the output and we are done */
for (char *rev = buf; rev < out;) {
char t = *--out;
*out = *rev;
*rev++ = t;
}
return buf;
fail:
free(mybuf);
UnLock(dirlock);
return NULL;
}