diff options
| author | Yuqian Yang <crupest@crupest.life> | 2025-04-01 23:44:50 +0800 | 
|---|---|---|
| committer | Yuqian Yang <crupest@crupest.life> | 2025-04-01 23:44:50 +0800 | 
| commit | a985d6bb3ee26db6444702c3c0c8bff53ba46824 (patch) | |
| tree | 8610b9a11c1cbd4e347e80a3bba4a191ae2abb7d /www/content/posts | |
| parent | 9d9b68f8fb70dc72f34f3dd41f5811529e09789b (diff) | |
| download | crupest-a985d6bb3ee26db6444702c3c0c8bff53ba46824.tar.gz crupest-a985d6bb3ee26db6444702c3c0c8bff53ba46824.tar.bz2 crupest-a985d6bb3ee26db6444702c3c0c8bff53ba46824.zip | |
feat(www): add cheat-sheet.
Diffstat (limited to 'www/content/posts')
| -rw-r--r-- | www/content/posts/c-func-ext.md | 80 | 
1 files changed, 71 insertions, 9 deletions
| diff --git a/www/content/posts/c-func-ext.md b/www/content/posts/c-func-ext.md index f5ab8fb..f0fce10 100644 --- a/www/content/posts/c-func-ext.md +++ b/www/content/posts/c-func-ext.md @@ -8,16 +8,78 @@ tags:    - posix  --- -Recently, I've been working on porting libraries to GNU/Hurd. The maintainers of GNU/Hurd -have a strong belief that [`*_MAX` macros on POSIX system interfaces](https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/nframe.html) -are very evil things. This is indeed true as a lot of (old) libraries relying on those macros -to determine the buffer size. In modern programming world, it is definitely a bad -idea to use fixed values for buffer sizes without considering possible overflow, unless -you are certain that size is sufficient. - -When you get rid of some old things, you will always meet compatibility problems. In these -case, old source codes using these macros just do not compile now. So here are some +Recently, I’ve been working on porting some libraries to GNU/Hurd. Many (old) +libraries use [`*_MAX` constants on POSIX system +interfaces](https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/nframe.html) +to calculate buffer sizes. However, the GNU/Hurd maintainers urge against the +blind use of them and refuse to define them in system headers. When old APIs are +gone, compatibility problems come. To make my life easier, I'll put some +reusable code snippets here to help *fix `*_MAX` bugs*.  <!--more--> +```c +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> + +static inline char *xreadlink(const char *restrict path) { +  char *buffer; +  size_t allocated = 128; +  ssize_t len; + +  while (1) { +    buffer = (char *)malloc(allocated); +    if (!buffer) { +      return NULL; +    } +    len = readlink(path, buffer, allocated); +    if (len < (ssize_t)allocated) { +      return buffer; +    } +    free(buffer); +    if (len >= (ssize_t)allocated) { +      allocated *= 2; +      continue; +    } +    return NULL; +  } +} + +static inline char *xgethostname() { +  long max_host_name; +  char *buffer; + +  max_host_name = sysconf(_SC_HOST_NAME_MAX); +  buffer = malloc(max_host_name + 1); + +  if (gethostname(buffer, max_host_name + 1)) { +    free(buffer); +    return NULL; +  } + +  buffer[max_host_name] = '\0'; +  return buffer; +} + +static inline char *xgetcwd() { +  char *buffer; +  size_t allocated = 128; +  while (1) { +    buffer = (char *)malloc(allocated); +    if (!buffer) { +      return NULL; +    } +    getcwd(buffer, allocated); +    if (buffer) +      return buffer; +    free(buffer); +    if (errno == ERANGE) { +      allocated *= 2; +      continue; +    } +    return NULL; +  } +} +``` | 
