libmisc/write_full.c: Improve write_full()
Documentation: - Correct the comment documenting the function: write_full() doesn't write "up to" count bytes (which is write(2)'s behavior, and exactly what this function is designed to avoid), but rather exactly count bytes (on success). - While fixing the documentation, take the time to add a man-page-like comment as in other APIs. Especially, since we'll have to document a few other changes from this patch, such as the modified return values. - Partial writes are still possible on error. It's the caller's responsibility to handle that possibility. API: - In write(2), it's useful to know how many bytes were transferred, since it can have short writes. In this API, since it either writes it all or fails, that value is useless, and callers only want to know if it succeeded or not. Thus, just return 0 or -1. Implementation: - Use `== -1` instead of `< 0` to check for write(2) syscall errors. This is wisdom from Michael Kerrisk. This convention is useful because it more explicitly tells maintainers that the only value which can lead to that path is -1. Otherwise, a maintainer of the code might be confused to think that other negative values are possible. Keep it simple. - The path under `if (res == 0)` was unreachable, since the loop condition `while (count > 0)` precludes that possibility. Remove the dead code. - Use a temporary variable of type `const char *` to avoid a cast. - Rename `res`, which just holds the result from write(2), to `w`, which more clearly shows that it's just a very-short-lived variable (by it's one-letter name), and also relates itself more to write(2). I find it more readable. - Move the definition of `w` to the top of the function. Now that the function is significantly shorter, the lifetime of the variable is clearer, and I find it more readable this way. Use: - Also use `== -1` to check errors. Cc: Christian Göttsche <cgzones@googlemail.com> Cc: Serge Hallyn <serge@hallyn.com> Signed-off-by: Alejandro Colomar <alx@kernel.org>
This commit is contained in:
committed by
Serge Hallyn
parent
890f911e17
commit
f45498a6c2
+1
-1
@@ -400,7 +400,7 @@ static void exit_handler (unused int sig)
|
||||
|
||||
static void alarm_handler (unused int sig)
|
||||
{
|
||||
write_full (STDERR_FILENO, tmsg, strlen (tmsg));
|
||||
write_full(STDERR_FILENO, tmsg, strlen(tmsg));
|
||||
signal(SIGALRM, exit_handler);
|
||||
alarm(2);
|
||||
}
|
||||
|
||||
@@ -164,9 +164,9 @@ static void kill_child (int unused(s))
|
||||
{
|
||||
if (0 != pid_child) {
|
||||
(void) kill (-pid_child, SIGKILL);
|
||||
(void) write_full (STDERR_FILENO, kill_msg, strlen (kill_msg));
|
||||
(void) write_full(STDERR_FILENO, kill_msg, strlen(kill_msg));
|
||||
} else {
|
||||
(void) write_full (STDERR_FILENO, wait_msg, strlen (wait_msg));
|
||||
(void) write_full(STDERR_FILENO, wait_msg, strlen(wait_msg));
|
||||
}
|
||||
_exit (255);
|
||||
}
|
||||
|
||||
+1
-1
@@ -2067,7 +2067,7 @@ static void faillog_reset (uid_t uid)
|
||||
return;
|
||||
}
|
||||
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
||||
|| (write_full (fd, &fl, sizeof (fl)) != (ssize_t) sizeof (fl))
|
||||
|| (write_full(fd, &fl, sizeof (fl)) == -1)
|
||||
|| (fsync (fd) != 0)) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to reset the faillog entry of UID %lu: %s\n"),
|
||||
|
||||
+5
-4
@@ -1941,7 +1941,7 @@ static void update_lastlog (void)
|
||||
&& (read (fd, &ll, sizeof ll) == (ssize_t) sizeof ll)) {
|
||||
/* Copy the old entry to its new location */
|
||||
if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
|
||||
|| (write_full (fd, &ll, sizeof ll) != (ssize_t) sizeof ll)
|
||||
|| (write_full(fd, &ll, sizeof ll) == -1)
|
||||
|| (fsync (fd) != 0)) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"),
|
||||
@@ -1957,7 +1957,7 @@ static void update_lastlog (void)
|
||||
/* Reset the new uid's lastlog entry */
|
||||
memzero (&ll, sizeof (ll));
|
||||
if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
|
||||
|| (write_full (fd, &ll, sizeof ll) != (ssize_t) sizeof ll)
|
||||
|| (write_full(fd, &ll, sizeof ll) == -1)
|
||||
|| (fsync (fd) != 0)) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"),
|
||||
@@ -2001,7 +2001,7 @@ static void update_faillog (void)
|
||||
&& (read (fd, &fl, sizeof fl) == (ssize_t) sizeof fl)) {
|
||||
/* Copy the old entry to its new location */
|
||||
if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
|
||||
|| (write_full (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)
|
||||
|| (write_full(fd, &fl, sizeof fl) == -1)
|
||||
|| (fsync (fd) != 0)) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"),
|
||||
@@ -2017,7 +2017,8 @@ static void update_faillog (void)
|
||||
/* Reset the new uid's faillog entry */
|
||||
memzero (&fl, sizeof (fl));
|
||||
if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
|
||||
|| (write_full (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)) {
|
||||
|| (write_full(fd, &fl, sizeof fl) == -1))
|
||||
{
|
||||
fprintf (stderr,
|
||||
_("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"),
|
||||
Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno));
|
||||
|
||||
Reference in New Issue
Block a user