summaryrefslogtreecommitdiffstats
path: root/src/providers
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2010-06-08 15:47:34 -0400
committerStephen Gallagher <sgallagh@redhat.com>2010-06-10 10:17:21 -0400
commitcedc75748b155f7c1287de8796409dd79ef7aecd (patch)
tree68eab2b23f83565f0e293066c30aa339990d6c6a /src/providers
parentca95af6e15ddc8928684327ff05353b1e3a17acd (diff)
downloadsssd-cedc75748b155f7c1287de8796409dd79ef7aecd.tar.gz
sssd-cedc75748b155f7c1287de8796409dd79ef7aecd.tar.xz
sssd-cedc75748b155f7c1287de8796409dd79ef7aecd.zip
Properly handle read() and write() throughout the SSSD
We need to guarantee at all times that reads and writes complete successfully. This means that they must be checked for returning EINTR and EAGAIN, and all writes must be wrapped in a loop to ensure that they do not truncate their output.
Diffstat (limited to 'src/providers')
-rw-r--r--src/providers/krb5/krb5_common.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
index c78f0e60c..fbc308895 100644
--- a/src/providers/krb5/krb5_common.c
+++ b/src/providers/krb5/krb5_common.c
@@ -158,6 +158,7 @@ errno_t write_krb5info_file(const char *realm, const char *server,
TALLOC_CTX *tmp_ctx = NULL;
const char *name_tmpl = NULL;
int server_len;
+ ssize_t written;
if (realm == NULL || *realm == '\0' || server == NULL || *server == '\0' ||
service == NULL || service == '\0') {
@@ -203,14 +204,24 @@ errno_t write_krb5info_file(const char *realm, const char *server,
goto done;
}
- ret = write(fd, server, server_len);
- if (ret == -1) {
- DEBUG(1, ("write failed [%d][%s].\n", errno, strerror(errno)));
- goto done;
+ written = 0;
+ while (written < server_len) {
+ ret = write(fd, server+written, server_len-written);
+ if (ret == -1) {
+ if (errno == EINTR || errno == EAGAIN) {
+ continue;
+ }
+ DEBUG(1, ("write failed [%d][%s].\n", errno, strerror(errno)));
+ goto done;
+ }
+ else {
+ written += ret;
+ }
}
- if (ret != server_len) {
- DEBUG(1, ("Partial write occured, this should never happen.\n"));
- ret = EINTR;
+
+ if (written != server_len) {
+ DEBUG(1, ("Write error, wrote [%d] bytes, expected [%d]\n",
+ written, server_len));
goto done;
}