summaryrefslogtreecommitdiff
path: root/src/stat.c
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2010-07-05 17:18:29 +0200
committerJim Meyering <meyering@redhat.com>2010-07-05 17:39:51 +0200
commitd5427265e30522cfda098bb82ad3d4bff0a0d2bd (patch)
treedd0c0a621a0a7e2fd6415986f1e59f2414e1f13e /src/stat.c
parent61aae73f5427c987b20604fbec5772e02edc0f74 (diff)
downloadcoreutils-d5427265e30522cfda098bb82ad3d4bff0a0d2bd.tar.xz
stat: getfilecon failure now evokes nonzero exit status
Add comments and adjust interfaces to allow low-level failure to propagate out to callers. * src/stat.c (out_file_context): Return bool, not void, so we can tell callers about failure. (print_statfs, print_stat, print_it): Propagate failure to caller. (do_statfs): Propagate print_it failure to caller. (do_stat): Likewise. I nearly forgot to update do_stat to propagate print_it failure, and it compiled just fine in spite of that. To prevent possibility of a repeat, I've marked each function that returns non-void with ATTRIBUTE_WARN_UNUSED_RESULT.
Diffstat (limited to 'src/stat.c')
-rw-r--r--src/stat.c60
1 files changed, 38 insertions, 22 deletions
diff --git a/src/stat.c b/src/stat.c
index f1b5ef110..c3730f0b1 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -88,7 +88,7 @@
/* BeOS has a statvfs function, but it does not return sensible values
for f_files, f_ffree and f_favail, and lacks f_type, f_basetype and
f_fstypename. Use 'struct fs_info' instead. */
-static int
+static int ATTRIBUTE_WARN_UNUSED_RESULT
statfs (char const *filename, struct fs_info *buf)
{
dev_t device = dev_for_path (filename);
@@ -185,7 +185,7 @@ static char const *trailing_delim = "";
Others have statfs.f_fstypename[MFSNAMELEN] (NetBSD 1.5.2).
Still others have neither and have to get by with f_type (GNU/Linux).
But f_type may only exist in statfs (Cygwin). */
-static char const *
+static char const * ATTRIBUTE_WARN_UNUSED_RESULT
human_fstype (STRUCT_STATVFS const *statfsbuf)
{
#ifdef STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME
@@ -436,7 +436,7 @@ human_fstype (STRUCT_STATVFS const *statfsbuf)
#endif
}
-static char *
+static char * ATTRIBUTE_WARN_UNUSED_RESULT
human_access (struct stat const *statbuf)
{
static char modebuf[12];
@@ -445,7 +445,7 @@ human_access (struct stat const *statbuf)
return modebuf;
}
-static char *
+static char * ATTRIBUTE_WARN_UNUSED_RESULT
human_time (struct timespec t)
{
static char str[MAX (INT_BUFSIZE_BOUND (intmax_t),
@@ -491,11 +491,14 @@ out_uint_x (char *pformat, size_t prefix_len, uintmax_t arg)
}
/* Very specialized function (modifies FORMAT), just so as to avoid
- duplicating this code between both print_statfs and print_stat. */
-static void
+ duplicating this code between both print_statfs and print_stat.
+ Return zero upon success, nonzero upon failure. */
+static bool ATTRIBUTE_WARN_UNUSED_RESULT
out_file_context (char const *filename, char *pformat, size_t prefix_len)
{
char *scontext;
+ bool fail = false;
+
if ((follow_links
? getfilecon (filename, &scontext)
: lgetfilecon (filename, &scontext)) < 0)
@@ -503,19 +506,22 @@ out_file_context (char const *filename, char *pformat, size_t prefix_len)
error (0, errno, _("failed to get security context of %s"),
quote (filename));
scontext = NULL;
+ fail = true;
}
strcpy (pformat + prefix_len, "s");
printf (pformat, (scontext ? scontext : "?"));
if (scontext)
freecon (scontext);
+ return fail;
}
-/* print statfs info */
-static void
+/* Print statfs info. Return zero upon success, nonzero upon failure. */
+static bool ATTRIBUTE_WARN_UNUSED_RESULT
print_statfs (char *pformat, size_t prefix_len, char m, char const *filename,
void const *data)
{
STRUCT_STATVFS const *statfsbuf = data;
+ bool fail = false;
switch (m)
{
@@ -589,22 +595,24 @@ print_statfs (char *pformat, size_t prefix_len, char m, char const *filename,
out_int (pformat, prefix_len, statfsbuf->f_ffree);
break;
case 'C':
- out_file_context (filename, pformat, prefix_len);
+ fail |= out_file_context (filename, pformat, prefix_len);
break;
default:
fputc ('?', stdout);
break;
}
+ return fail;
}
-/* print stat info */
-static void
+/* Print stat info. Return zero upon success, nonzero upon failure. */
+static bool
print_stat (char *pformat, size_t prefix_len, char m,
char const *filename, void const *data)
{
struct stat *statbuf = (struct stat *) data;
struct passwd *pw_ent;
struct group *gw_ent;
+ bool fail = false;
switch (m)
{
@@ -620,7 +628,7 @@ print_stat (char *pformat, size_t prefix_len, char m,
{
error (0, errno, _("cannot read symbolic link %s"),
quote (filename));
- return;
+ return true;
}
printf (" -> ");
out_string (pformat, prefix_len, quote (linkname));
@@ -714,12 +722,13 @@ print_stat (char *pformat, size_t prefix_len, char m,
out_uint (pformat, prefix_len, statbuf->st_ctime);
break;
case 'C':
- out_file_context (filename, pformat, prefix_len);
+ fail |= out_file_context (filename, pformat, prefix_len);
break;
default:
fputc ('?', stdout);
break;
}
+ return fail;
}
/* Output a single-character \ escape. */
@@ -763,11 +772,16 @@ print_esc_char (char c)
putchar (c);
}
-static void
+/* Print the information specified by the format string, FORMAT,
+ calling PRINT_FUNC for each %-directive encountered.
+ Return zero upon success, nonzero upon failure. */
+static bool ATTRIBUTE_WARN_UNUSED_RESULT
print_it (char const *format, char const *filename,
- void (*print_func) (char *, size_t, char, char const *, void const *),
+ bool (*print_func) (char *, size_t, char, char const *, void const *),
void const *data)
{
+ bool fail = false;
+
/* Add 2 to accommodate our conversion of the stat `%s' format string
to the longer printf `%llu' one. */
enum
@@ -807,7 +821,7 @@ print_it (char const *format, char const *filename,
putchar ('%');
break;
default:
- print_func (dest, len + 1, *fmt_char, filename, data);
+ fail |= print_func (dest, len + 1, *fmt_char, filename, data);
break;
}
break;
@@ -866,10 +880,12 @@ print_it (char const *format, char const *filename,
free (dest);
fputs (trailing_delim, stdout);
+
+ return fail;
}
/* Stat the file system and print what we find. */
-static bool
+static bool ATTRIBUTE_WARN_UNUSED_RESULT
do_statfs (char const *filename, bool terse, char const *format)
{
STRUCT_STATVFS statfsbuf;
@@ -899,12 +915,12 @@ do_statfs (char const *filename, bool terse, char const *format)
"Inodes: Total: %-10c Free: %d\n");
}
- print_it (format, filename, print_statfs, &statfsbuf);
- return true;
+ bool fail = print_it (format, filename, print_statfs, &statfsbuf);
+ return ! fail;
}
/* stat the file and print what we find */
-static bool
+static bool ATTRIBUTE_WARN_UNUSED_RESULT
do_stat (char const *filename, bool terse, char const *format)
{
struct stat statbuf;
@@ -959,8 +975,8 @@ do_stat (char const *filename, bool terse, char const *format)
}
}
}
- print_it (format, filename, print_stat, &statbuf);
- return true;
+ bool fail = print_it (format, filename, print_stat, &statbuf);
+ return ! fail;
}
void