* Thus, when their signature changes, they don't need updates in a .h
* file somewhere, but they do need updates in the Lisp code. FIXME:
* It would be nice to enforce this at compile time. It mighn't even
- * be all that hard: make the cross-compiler versions of DEF-ALIEN-FOO
+ * be all that hard: make the cross-compiler versions of DEFINE-ALIEN-FOO
* macros accumulate strings in a list which then gets written out at
* the end of sbcl2.h at the end of cross-compilation, then rerun
* 'make' in src/runtime/ using the new sbcl2.h as sbcl.h (and make
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <pwd.h>
+#include <stdio.h>
#include "runtime.h"
#include "sbcl.h"
#include "util.h"
+
+/* KLUDGE: Neither the OpenBSD nor the Linux man page give a header
+ * file to find this in (?). -- WHN 2002-02-07 */
+extern char **environ;
\f
/*
* stuff needed by CL:DIRECTORY and other Lisp directory operations
char**
alloc_directory_lispy_filenames(const char *directory_name)
{
- DIR *dir_ptr;
+ DIR *dir_ptr = opendir(directory_name);
char **result = 0;
- if (dir_ptr = opendir(directory_name)) { /* if opendir success */
+ if (dir_ptr) { /* if opendir success */
struct voidacc va;
if (0 == voidacc_ctor(&va)) { /* if voidacc_ctor success */
struct dirent *dirent_ptr;
- while (dirent_ptr = readdir(dir_ptr)) { /* until end of data */
+ while ( (dirent_ptr = readdir(dir_ptr)) ) { /* until end of data */
char* original_name = dirent_ptr->d_name;
if (is_lispy_filename(original_name)) {
/* strdup(3) is in Linux and *BSD. If you port
/* a wrapped version of readlink(2):
* -- If path isn't a symlink, or is a broken symlink, return 0.
* -- If path is a symlink, return a newly allocated string holding
- * the thing it's linked to.
- */
+ * the thing it's linked to. */
char *
wrapped_readlink(char *path)
{
- int strlen_path = strlen(path);
int bufsiz = strlen(path) + 16;
while (1) {
char *result = malloc(bufsiz);
- int n_read = readlink(path, result, n_read);
+ int n_read = readlink(path, result, bufsiz);
if (n_read < 0) {
+ free(result);
return 0;
} else if (n_read < bufsiz) {
result[n_read] = 0;
copy_to_stat_wrapper(buf, &real_buf);
return ret;
}
+\f
+/*
+ * getpwuid() stuff
+ */
+
+/* Return a newly-allocated string holding the username for "uid", or
+ * NULL if there's no such user.
+ *
+ * KLUDGE: We also return NULL if malloc() runs out of memory
+ * (returning strdup() result) since it's not clear how to handle that
+ * error better. -- WHN 2001-12-28 */
+char *
+uid_username(int uid)
+{
+ struct passwd *p = getpwuid(uid);
+ if (p) {
+ /* The object *p is a static struct which'll be overwritten by
+ * the next call to getpwuid(), so it'd be unsafe to return
+ * p->pw_name without copying. */
+ return strdup(p->pw_name);
+ } else {
+ return 0;
+ }
+}
+
+char *
+uid_homedir(uid_t uid)
+{
+ struct passwd *p = getpwuid(uid);
+ if(p) {
+ /* Let's be careful about this, shall we? */
+ size_t len = strlen(p->pw_dir);
+ if (p->pw_dir[len-1] == '/') {
+ return strdup(p->pw_dir);
+ } else {
+ char *result = malloc(len + 2);
+ if (result) {
+ int nchars = sprintf(result,"%s/",p->pw_dir);
+ if (nchars == len + 1) {
+ return result;
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ }
+ } else {
+ return 0;
+ }
+}
+\f
+/*
+ * functions to get miscellaneous C-level variables
+ *
+ * (Doing this by calling functions lets us borrow the smarts of the C
+ * linker, so that things don't blow up when libc versions and thus
+ * variable locations change between compile time and run time.)
+ */
+
+char **
+wrapped_environ()
+{
+ return environ;
+}