<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-size:small">Hi Richard,</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Richard Palethorpe <<a href="mailto:rpalethorpe@suse.com" target="_blank">rpalethorpe@suse.com</a>> wrote:<br></div><div dir="ltr" class="gmail_attr"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail_default" style="font-size:small">...</span><br>
+char *tst_decode_fd(int fd);<br>
+<br>
+int safe_openat(const char *file, const int lineno,<br>
+               int dirfd, const char *path, int oflags, ...);<br>
+<br>
+ssize_t safe_file_readat(const char *file, const int lineno,<br>
+                        int dirfd, const char *path, char *buf, size_t nbyte);<br>
+<br>
+int tst_file_vprintfat(int dirfd, const char *path, const char *fmt, va_list va);<br>
+int tst_file_printfat(int dirfd, const char *path, const char *fmt, ...)<br>
+                       __attribute__ ((format (printf, 3, 4)));<br>
+<br>
+int safe_file_vprintfat(const char *file, const int lineno,<br>
+                       int dirfd, const char *path,<br>
+                       const char *fmt, va_list va);<br>
+<br>
+int safe_file_printfat(const char *file, const int lineno,<br>
+                      int dirfd, const char *path, const char *fmt, ...)<br>
+                       __attribute__ ((format (printf, 5, 6)));<br>
+<br>
+int safe_unlinkat(const char *file, const int lineno,<br>
+                 int dirfd, const char *path, int flags);<br></blockquote><div><br></div><div><div class="gmail_default" style="font-size:small">I guess these prototypes should be moved to "safe_file_ops_fn.h"?</div><div class="gmail_default" style="font-size:small">(It seems the author did that on purpose to separate macros and function declaration)</div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
--- /dev/null<br>
+++ b/lib/tst_safe_file_ops.c<br></blockquote><div><br></div><div><div class="gmail_default" style="font-size:small">Then we can achieve all the above functions in "lib/safe_file_ops.c" without creating a new file.</div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
@@ -0,0 +1,171 @@<br>
+#define _GNU_SOURCE<br>
+#include <stdio.h><br>
+#include <stdlib.h><br>
+#include "lapi/fcntl.h"<br>
+<br>
+#define TST_NO_DEFAULT_MAIN<br>
+#include "tst_test.h"<br>
+<br>
+char fd_path[PATH_MAX];<br>
+<br>
+char *tst_decode_fd(int fd)<br>
+{<br>
+       ssize_t ret;<br>
+       char proc_path[32];<br>
+<br>
+       if (fd < 0)<br>
+               return "!";<br>
+<br>
+       sprintf(proc_path, "/proc/self/fd/%d", fd);<br>
+       ret = readlink(proc_path, fd_path, sizeof(fd_path));<br>
+<br>
+       if (ret < 0)<br>
+               return "?";<br>
+<br>
+       fd_path[ret] = '\0';<br>
+<br>
+       return fd_path;<br>
+}<br>
+<br>
+int safe_openat(const char *file, const int lineno,<br>
+               int dirfd, const char *path, int oflags, ...)<br>
+{<br>
+       va_list ap;<br>
+       int fd;<br>
+       mode_t mode;<br>
+<br>
+       va_start(ap, oflags);<br>
+       mode = va_arg(ap, int);<br>
+       va_end(ap);<br>
+<br>
+       fd = openat(dirfd, path, oflags, mode);<br>
+       if (fd > -1)<br>
+               return fd;<br>
+<br>
+       tst_brk_(file, lineno, TBROK | TERRNO,<br>
+                "openat(%d<%s>, '%s', %o, %o)",<br>
+                dirfd, tst_decode_fd(dirfd), path, oflags, mode);<br>
+<br>
+       return fd;<br>
+}<br>
+<br>
+ssize_t safe_file_readat(const char *file, const int lineno,<br>
+                        int dirfd, const char *path, char *buf, size_t nbyte)<br>
+{<br>
+       int fd = safe_openat(file, lineno, dirfd, path, O_RDONLY);<br>
+       ssize_t rval;<br>
+<br>
+       if (fd < 0)<br>
+               return -1;<br>
+<br>
+       rval = safe_read(file, lineno, NULL, 0, fd, buf, nbyte - 1);<br>
+       if (rval < 0)<br>
+               return -1;<br>
+<br>
+       close(fd);<br>
+       buf[rval] = '\0';<br>
+<br>
+       if (rval >= (ssize_t)nbyte - 1) {<br>
+               tst_brk_(file, lineno, TBROK,<br>
+                       "Buffer length %zu too small to read %d<%s>/%s",<br>
+                       nbyte, dirfd, tst_decode_fd(dirfd), path);<br>
+       }<br>
+<br>
+       return rval;<br>
+}<br>
+<br>
+int tst_file_vprintfat(int dirfd, const char *path, const char *fmt, va_list va)<br>
+{<br>
+       int fd = openat(dirfd, path, O_WRONLY);<br>
+<br>
+       if (fd < 0)<br>
+               return -1;<br>
+<br>
+       TEST(vdprintf(fd, fmt, va));<br>
+       close(fd);<br>
+<br>
+       if (TST_RET < 0) {<br>
+               errno = TST_ERR;<br>
+               return -2;<br>
+       }<br>
+<br>
+       return TST_RET;<br>
+}<br>
+<br>
+int tst_file_printfat(int dirfd, const char *path, const char *fmt, ...)<br>
+{<br>
+       va_list va;<br>
+       int rval;<br>
+<br>
+       va_start(va, fmt);<br>
+       rval = tst_file_vprintfat(dirfd, path, fmt, va);<br>
+       va_end(va);<br>
+<br>
+       return rval;<br>
+}<br>
+<br>
+int safe_file_vprintfat(const char *file, const int lineno,<br>
+                       int dirfd, const char *path,<br>
+                       const char *fmt, va_list va)<br>
+{<br>
+       char buf[16];<br>
+       va_list vac;<br>
+       int rval;<br>
+<br>
+       va_copy(vac, va);<br>
+<br>
+       TEST(tst_file_vprintfat(dirfd, path, fmt, va));<br>
+<br>
+       if (TST_RET == -2) {<br>
+               rval = vsnprintf(buf, sizeof(buf), fmt, vac);<br>
+               va_end(vac);<br>
+<br>
+               if (rval >= (ssize_t)sizeof(buf))<br>
+                       strcpy(buf + sizeof(buf) - 5, "...");<br>
+<br>
+               tst_brk_(file, lineno, TBROK | TTERRNO,<br>
+                        "vdprintf(%d<%s>, '%s', '%s'<%s>)",<br>
+                        dirfd, tst_decode_fd(dirfd), path, fmt,<br>
+                        rval > 0 ? buf : "???");<br>
+               return -1;<br>
+       }<br>
+<br>
+       va_end(vac);<br>
+<br>
+       if (TST_RET == -1) {<br>
+               tst_brk_(file, lineno, TBROK | TTERRNO,<br>
+                       "openat(%d<%s>, '%s', O_WRONLY)",<br>
+                       dirfd, tst_decode_fd(dirfd), path);<br>
+       }<br>
+<br>
+       return TST_RET;<br>
+}<br>
+<br>
+int safe_file_printfat(const char *file, const int lineno,<br>
+                      int dirfd, const char *path,<br>
+                      const char *fmt, ...)<br>
+{<br>
+       va_list va;<br>
+       int rval;<br>
+<br>
+       va_start(va, fmt);<br>
+       rval = safe_file_vprintfat(file, lineno, dirfd, path, fmt, va);<br>
+       va_end(va);<br>
+<br>
+       return rval;<br>
+}<br>
+<br>
+int safe_unlinkat(const char *file, const int lineno,<br>
+                 int dirfd, const char *path, int flags)<br>
+{<br>
+       int rval = unlinkat(dirfd, path, flags);<br>
+<br>
+       if (rval > -1)<br>
+               return rval;<br>
+<br>
+       tst_brk_(file, lineno, TBROK | TERRNO,<br>
+                "unlinkat(%d<%s>, '%s', %s)", dirfd, tst_decode_fd(dirfd), path,<br>
+                flags == AT_REMOVEDIR ? "AT_REMOVEDIR" : (flags ? "?" : "0"));<br>
+<br>
+       return rval;<br>
+}<br>
-- <br>
2.30.0<br>
<br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr"><div dir="ltr"><div>Regards,<br></div><div>Li Wang<br></div></div></div></div>