Hi,
This two patches will allow to remove a xmalloc and bail out early in case of
ENOMEM
I plan to implement a API reusing openat_permissive()
If openat_permissive cwd_errno is NULL use the slow but safe fork variant
else use the fchdir variant
Program that care could therefore use the more permissive variant (like for
instance the critical fts without FTS_NOCHDIR)
I program also to implement *at_permissive function
What do you think about that?
How could I easilly test this fallback under my quite recent debian ? Does I
need to compile under a qemu image of old os ? Where
could I find such an os ?
Bastien
From 65e47bc25f033afd627d5f25daf5f1833aa4922b Mon Sep 17 00:00:00 2001
From: Bastien ROUCARIES <[email protected]>
Date: Tue, 11 Jan 2011 13:05:54 +0100
Subject: [PATCH 2/3] Use malloc instead of xmalloc in openat-proc
Use malloc instead of xmalloc in openat-proc. In case of faillure, all caller fall back to slow fdir path.
---
lib/openat-proc.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/lib/openat-proc.c b/lib/openat-proc.c
index 51a8aa2..5868e5d 100644
--- a/lib/openat-proc.c
+++ b/lib/openat-proc.c
@@ -26,13 +26,14 @@
#include <fcntl.h>
#include <stdio.h>
+#include <stdlib.h>
+
#include <string.h>
#include <unistd.h>
#include "dirname.h"
#include "intprops.h"
#include "same-inode.h"
-#include "xalloc.h"
/* The results of open() in this file are not used with fchdir,
and we do not leak fds to any single-threaded code that could use stdio,
@@ -42,6 +43,9 @@
#undef open
#undef close
+/* use system definition of malloc here allocation is alway > 1 */
+#undef malloc
+
#define PROC_SELF_FD_FORMAT "/proc/self/fd/%d/%s"
#define PROC_SELF_FD_NAME_SIZE_BOUND(len) \
@@ -98,7 +102,7 @@ openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file)
else
{
size_t bufsize = PROC_SELF_FD_NAME_SIZE_BOUND (strlen (file));
- char *result = (bufsize < OPENAT_BUFFER_SIZE ? buf : xmalloc (bufsize));
+ char *result = (bufsize < OPENAT_BUFFER_SIZE ? buf : malloc (bufsize));
sprintf (result, PROC_SELF_FD_FORMAT, fd, file);
return result;
}
--
1.7.1
From 6cb8f64a3bf07c809b6f5f13b89f75daf41c0c84 Mon Sep 17 00:00:00 2001
From: Bastien ROUCARIES <bast...@portablebastien.(none)>
Date: Tue, 11 Jan 2011 13:32:26 +0100
Subject: [PATCH 3/3] Add errno return to openat_proc_name
Add errno return in order to clarify some error condition on caller
---
lib/fdopendir.c | 4 ++++
lib/openat-proc.c | 13 ++++++++++++-
lib/openat.c | 3 +++
3 files changed, 19 insertions(+), 1 deletions(-)
diff --git a/lib/fdopendir.c b/lib/fdopendir.c
index 0853e59..acdc24a 100644
--- a/lib/fdopendir.c
+++ b/lib/fdopendir.c
@@ -145,6 +145,10 @@ fd_clone_opendir (int fd, struct saved_cwd const *cwd)
int saved_errno = EOPNOTSUPP;
char buf[OPENAT_BUFFER_SIZE];
char *proc_file = openat_proc_name (buf, fd, ".");
+
+ if(NULL == proc_file && ENOMEM == errno)
+ return NULL;
+
if (proc_file)
{
dir = opendir (proc_file);
diff --git a/lib/openat-proc.c b/lib/openat-proc.c
index 5868e5d..534ca90 100644
--- a/lib/openat-proc.c
+++ b/lib/openat-proc.c
@@ -31,6 +31,8 @@
#include <string.h>
#include <unistd.h>
+#include <errno.h>
+
#include "dirname.h"
#include "intprops.h"
#include "same-inode.h"
@@ -66,6 +68,7 @@ openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file)
if (!*file)
{
buf[0] = '\0';
+ errno = ENOENT;
return buf;
}
@@ -98,11 +101,19 @@ openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file)
}
if (proc_status < 0)
- return NULL;
+ {
+ errno = EOPNOTSUPP;
+ return NULL;
+ }
else
{
size_t bufsize = PROC_SELF_FD_NAME_SIZE_BOUND (strlen (file));
char *result = (bufsize < OPENAT_BUFFER_SIZE ? buf : malloc (bufsize));
+ if(result == NULL)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
sprintf (result, PROC_SELF_FD_FORMAT, fd, file);
return result;
}
diff --git a/lib/openat.c b/lib/openat.c
index 55e12e2..9ef4b00 100644
--- a/lib/openat.c
+++ b/lib/openat.c
@@ -178,6 +178,9 @@ openat_permissive (int fd, char const *file, int flags, mode_t mode,
{
char buf[OPENAT_BUFFER_SIZE];
char *proc_file = openat_proc_name (buf, fd, file);
+ if(NULL == proc_file && ENOMEM == errno)
+ return -1;
+
if (proc_file)
{
int open_result = open (proc_file, flags, mode);
--
1.7.1