shadowio.c \
shadowio.h \
shadowmem.c \
- spawn.c
+ spawn.c \
+ write_full.c
if WITH_TCB
libshadow_la_SOURCES += tcbfuncs.c tcbfuncs.h
pid = getpid ();
snprintf (buf, sizeof buf, "%lu", (unsigned long) pid);
len = (ssize_t) strlen (buf) + 1;
- if (write (fd, buf, (size_t) len) != len) {
+ if (write_full (fd, buf, (size_t) len) != len) {
if (log) {
(void) fprintf (shadow_logfd,
"%s: %s file write error: %s\n",
/* valid.c */
extern bool valid (const char *, const struct passwd *);
+/* write_full.c */
+extern ssize_t write_full(int fd, const void *buf, size_t count);
+
/* xgetpwnam.c */
extern /*@null@*/ /*@only@*/struct passwd *xgetpwnam (const char *);
/* xprefix_getpwnam.c */
--- /dev/null
+/*
+ * SPDX-FileCopyrightText: 2023, Christian Göttsche <cgzones@googlemail.com>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <config.h>
+
+#ident "$Id$"
+
+#include "prototypes.h"
+
+#include <errno.h>
+#include <unistd.h>
+
+
+/*
+ * write_full - write entire buffer
+ *
+ * Write up to count bytes from the buffer starting at buf to the
+ * file referred to by the file descriptor fd.
+ * Retry in case of a short write.
+ *
+ * Returns the number of bytes written on success, -1 on error.
+ */
+ssize_t write_full(int fd, const void *buf, size_t count) {
+ ssize_t written = 0;
+
+ while (count > 0) {
+ ssize_t res;
+
+ res = write(fd, buf, count);
+ if (res < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+
+ return res;
+ }
+
+ if (res == 0) {
+ break;
+ }
+
+ written += res;
+ buf = (const unsigned char*)buf + res;
+ count -= res;
+ }
+
+ return written;
+}
return err;
}
-/*
- * full_write - write entire buffer
- *
- * Write up to count bytes from the buffer starting at buf to the
- * file referred to by the file descriptor fd.
- * Retry in case of a short write.
- *
- * Returns the number of bytes written on success, -1 on error.
- */
-static ssize_t full_write(int fd, const void *buf, size_t count) {
- ssize_t written = 0;
-
- while (count > 0) {
- ssize_t res;
-
- res = write(fd, buf, count);
- if (res < 0) {
- if (errno == EINTR) {
- continue;
- }
-
- return res;
- }
-
- if (res == 0) {
- break;
- }
-
- written += res;
- buf = (const unsigned char*)buf + res;
- count -= res;
- }
-
- return written;
-}
-
/*
* copy_file - copy a file
*
break;
}
- if (full_write (ofd, buf, cnt) < 0) {
+ if (write_full (ofd, buf, cnt) < 0) {
(void) close (ofd);
(void) close (ifd);
return -1;
#include "defines.h"
#include "faillog.h"
#include "failure.h"
+#include "prototypes.h"
#define YEAR (365L*DAY)
/*
* failure - make failure entry
*/
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
- || (write (fd, fl, sizeof *fl) != (ssize_t) sizeof *fl)
+ || (write_full (fd, fl, sizeof *fl) != (ssize_t) sizeof *fl)
|| (close (fd) != 0)) {
SYSLOG ((LOG_WARN,
"Can't write faillog entry for UID %lu in %s.",
fail.fail_cnt = 0;
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
- || (write (fd, &fail, sizeof fail) != (ssize_t) sizeof fail)
+ || (write_full (fd, &fail, sizeof fail) != (ssize_t) sizeof fail)
|| (close (fd) != 0)) {
SYSLOG ((LOG_WARN,
"Can't reset faillog entry for UID %lu in %s.",
log_get_progname(), map_file, strerror(errno));
exit(EXIT_FAILURE);
}
- if (write(fd, buf, pos - buf) != (pos - buf)) {
+ if (write_full(fd, buf, pos - buf) != (pos - buf)) {
fprintf(log_get_logfd(), _("%s: write to %s failed: %s\n"),
log_get_progname(), map_file, strerror(errno));
exit(EXIT_FAILURE);
strncpy (newlog.ll_host, host, sizeof (newlog.ll_host) - 1);
#endif
if ( (lseek (fd, offset, SEEK_SET) != offset)
- || (write (fd, &newlog, sizeof newlog) != (ssize_t) sizeof newlog)
+ || (write_full (fd, &newlog, sizeof newlog) != (ssize_t) sizeof newlog)
|| (close (fd) != 0)) {
SYSLOG ((LOG_WARN,
"Can't write lastlog entry for UID %lu in %s.",
* Append the new failure record and close the log file.
*/
- if ( (write (fd, failent, sizeof *failent) != (ssize_t) sizeof *failent)
+ if ( (write_full (fd, failent, sizeof *failent) != (ssize_t) sizeof *failent)
|| (close (fd) != 0)) {
SYSLOG ((LOG_WARN,
"Can't append failure of user %s to %s.",
fd = open (filename, O_APPEND | O_WRONLY, 0);
if (fd >= 0) {
- write (fd, ut, sizeof (*ut));
+ write_full (fd, ut, sizeof (*ut));
close (fd);
}
}
static void alarm_handler (unused int sig)
{
- write (STDERR_FILENO, tmsg, strlen (tmsg));
+ write_full (STDERR_FILENO, tmsg, strlen (tmsg));
signal(SIGALRM, exit_handler);
alarm(2);
}
{
if (0 != pid_child) {
(void) kill (-pid_child, SIGKILL);
- (void) write (STDERR_FILENO, kill_msg, strlen (kill_msg));
+ (void) write_full (STDERR_FILENO, kill_msg, strlen (kill_msg));
} else {
- (void) write (STDERR_FILENO, wait_msg, strlen (wait_msg));
+ (void) write_full (STDERR_FILENO, wait_msg, strlen (wait_msg));
}
_exit (255);
}
return;
}
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
- || (write (fd, &fl, sizeof (fl)) != (ssize_t) sizeof (fl))
+ || (write_full (fd, &fl, sizeof (fl)) != (ssize_t) sizeof (fl))
|| (fsync (fd) != 0)) {
fprintf (stderr,
_("%s: failed to reset the faillog entry of UID %lu: %s\n"),
return;
}
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
- || (write (fd, &ll, sizeof (ll)) != (ssize_t) sizeof (ll))
+ || (write_full (fd, &ll, sizeof (ll)) != (ssize_t) sizeof (ll))
|| (fsync (fd) != 0)) {
fprintf (stderr,
_("%s: failed to reset the lastlog entry of UID %lu: %s\n"),
&& (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 (fd, &ll, sizeof ll) != (ssize_t) sizeof ll)
+ || (write_full (fd, &ll, sizeof ll) != (ssize_t) sizeof ll)
|| (fsync (fd) != 0)) {
fprintf (stderr,
_("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"),
/* Reset the new uid's lastlog entry */
memzero (&ll, sizeof (ll));
if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
- || (write (fd, &ll, sizeof ll) != (ssize_t) sizeof ll)
+ || (write_full (fd, &ll, sizeof ll) != (ssize_t) sizeof ll)
|| (fsync (fd) != 0)) {
fprintf (stderr,
_("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"),
&& (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 (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)
+ || (write_full (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)
|| (fsync (fd) != 0)) {
fprintf (stderr,
_("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"),
/* Reset the new uid's faillog entry */
memzero (&fl, sizeof (fl));
if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
- || (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)) {
+ || (write_full (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)) {
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));