From c8c0844f7fbcb955848ca84432e5ffcf71f1cef1 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 2 Aug 2013 12:59:45 -0400 Subject: debloat code that depends on /proc/self/fd/%d with shared function I intend to add more Linux workarounds that depend on using these pathnames, and some of them will be in "syscall" functions that, from an anti-bloat standpoint, should not depend on the whole snprintf framework. --- src/internal/procfdname.c | 13 +++++++++++++ src/misc/realpath.c | 4 +++- src/process/fexecve.c | 7 ++++--- src/stat/fchmodat.c | 4 +++- src/unistd/ttyname_r.c | 4 +++- 5 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 src/internal/procfdname.c diff --git a/src/internal/procfdname.c b/src/internal/procfdname.c new file mode 100644 index 00000000..697e0bdc --- /dev/null +++ b/src/internal/procfdname.c @@ -0,0 +1,13 @@ +void __procfdname(char *buf, unsigned fd) +{ + unsigned i, j; + for (i=0; (buf[i] = "/proc/self/fd/"[i]); i++); + if (!fd) { + buf[i] = '0'; + buf[i+1] = 0; + return; + } + for (j=fd; j; j/=10, i++); + buf[i] = 0; + for (; fd; fd/=10) buf[--i] = '0' + fd%10; +} diff --git a/src/misc/realpath.c b/src/misc/realpath.c index 18335146..d238ed01 100644 --- a/src/misc/realpath.c +++ b/src/misc/realpath.c @@ -6,6 +6,8 @@ #include #include +void __procfdname(char *, unsigned); + char *realpath(const char *restrict filename, char *restrict resolved) { int fd; @@ -21,7 +23,7 @@ char *realpath(const char *restrict filename, char *restrict resolved) fd = open(filename, O_RDONLY|O_NONBLOCK|O_CLOEXEC); if (fd < 0) return 0; - snprintf(buf, sizeof buf, "/proc/self/fd/%d", fd); + __procfdname(buf, fd); if (!resolved) { alloc = 1; diff --git a/src/process/fexecve.c b/src/process/fexecve.c index 5939181a..8ab02a74 100644 --- a/src/process/fexecve.c +++ b/src/process/fexecve.c @@ -2,11 +2,12 @@ #include #include +void __procfdname(char *, unsigned); + int fexecve(int fd, char *const argv[], char *const envp[]) { - static const char proc[] = "/proc/self/fd/%d"; - char buf[sizeof proc + 3*sizeof(int)]; - snprintf(buf, sizeof buf, proc, fd); + char buf[15 + 3*sizeof(int)]; + __procfdname(buf, fd); execve(buf, argv, envp); if (errno == ENOENT) errno = EBADF; return -1; diff --git a/src/stat/fchmodat.c b/src/stat/fchmodat.c index c1410bc5..aeb50bc5 100644 --- a/src/stat/fchmodat.c +++ b/src/stat/fchmodat.c @@ -4,6 +4,8 @@ #include #include "syscall.h" +void __procfdname(char *, unsigned); + int fchmodat(int fd, const char *path, mode_t mode, int flag) { if (!flag) return syscall(SYS_fchmodat, fd, path, mode, flag); @@ -26,7 +28,7 @@ int fchmodat(int fd, const char *path, mode_t mode, int flag) return __syscall_ret(fd2); } - snprintf(proc, sizeof proc, "/proc/self/fd/%d", fd2); + __procfdname(proc, fd2); if (!(ret = __syscall(SYS_stat, proc, &st)) && !S_ISLNK(st.st_mode)) ret = __syscall(SYS_chmod, proc, mode); diff --git a/src/unistd/ttyname_r.c b/src/unistd/ttyname_r.c index 2255e2df..a2ce3511 100644 --- a/src/unistd/ttyname_r.c +++ b/src/unistd/ttyname_r.c @@ -3,6 +3,8 @@ #include #include +void __procfdname(char *, unsigned); + int ttyname_r(int fd, char *name, size_t size) { char procname[sizeof "/proc/self/fd/" + 3*sizeof(int) + 2]; @@ -10,7 +12,7 @@ int ttyname_r(int fd, char *name, size_t size) if (!isatty(fd)) return ENOTTY; - snprintf(procname, sizeof procname, "/proc/self/fd/%d", fd); + __procfdname(procname, fd); l = readlink(procname, name, size); if (l < 0) return errno; -- cgit v1.2.1