+ int r;
+ char *out;
+ size_t size;
+ FILE *fp;
+ DIR *dir;
+ struct dirent *d;
+ char fname[256], link[256];
+ struct stat statbuf;
+
+ fp = open_memstream (&out, &size);
+ if (!fp) {
+ reply_with_perror ("open_memstream");
+ return NULL;
+ }
+
+ dir = opendir ("/proc/self/fd");
+ if (!dir) {
+ reply_with_perror ("opendir: /proc/self/fd");
+ fclose (fp);
+ return NULL;
+ }
+
+ while ((d = readdir (dir)) != NULL) {
+ if (STREQ (d->d_name, ".") || STREQ (d->d_name, ".."))
+ continue;
+
+ snprintf (fname, sizeof fname, "/proc/self/fd/%s", d->d_name);
+
+ r = lstat (fname, &statbuf);
+ if (r == -1) {
+ reply_with_perror ("stat: %s", fname);
+ fclose (fp);
+ free (out);
+ closedir (dir);
+ return NULL;
+ }
+
+ if (S_ISLNK (statbuf.st_mode)) {
+ r = readlink (fname, link, sizeof link - 1);
+ if (r == -1) {
+ reply_with_perror ("readline: %s", fname);
+ fclose (fp);
+ free (out);
+ closedir (dir);
+ return NULL;
+ }
+ link[r] = '\0';
+
+ fprintf (fp, "%2s %s\n", d->d_name, link);
+ } else
+ fprintf (fp, "%2s 0%o\n", d->d_name, statbuf.st_mode);
+ }
+
+ fclose (fp);
+
+ if (closedir (dir) == -1) {
+ reply_with_perror ("closedir");
+ free (out);
+ return NULL;
+ }
+
+ return out;