From 9d7d4458d94d0aac0a7edf999368eb18f89cb76a Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Apr 20 2012 14:55:14 +0000 Subject: Convert read and write operations to sss_atomic_read https://fedorahosted.org/sssd/ticket/1209 --- diff --git a/Makefile.am b/Makefile.am index 919fb9b..8293c08 100644 --- a/Makefile.am +++ b/Makefile.am @@ -777,6 +777,7 @@ endif files_tests_SOURCES = \ src/tests/files-tests.c \ src/util/check_and_open.c \ + src/util/atomic_io.c \ src/tools/selinux.c \ src/tools/files.c files_tests_CFLAGS = \ @@ -835,6 +836,7 @@ fail_over_tests_LDADD = \ find_uid_tests_SOURCES = \ src/tests/find_uid-tests.c \ src/util/find_uid.c \ + src/util/atomic_io.c \ src/util/strtonum.c find_uid_tests_CFLAGS = \ $(AM_CFLAGS) \ @@ -1225,6 +1227,7 @@ krb5_child_SOURCES = \ src/providers/dp_pam_data_util.c \ src/util/user_info_msg.c \ src/util/sss_krb5.c \ + src/util/atomic_io.c \ src/util/util.c \ src/util/signal.c krb5_child_CFLAGS = \ @@ -1243,6 +1246,7 @@ krb5_child_LDADD = \ ldap_child_SOURCES = \ src/providers/ldap/ldap_child.c \ src/util/sss_krb5.c \ + src/util/atomic_io.c \ src/util/util.c \ src/util/signal.c ldap_child_CFLAGS = \ @@ -1284,7 +1288,8 @@ memberof_la_LDFLAGS = \ if BUILD_KRB5_LOCATOR_PLUGIN sssd_krb5_locator_plugin_la_SOURCES = \ - src/krb5_plugin/sssd_krb5_locator_plugin.c + src/krb5_plugin/sssd_krb5_locator_plugin.c \ + src/util/atomic_io.c sssd_krb5_locator_plugin_la_CFLAGS = \ $(AM_CFLAGS) \ $(KRB5_CFLAGS) diff --git a/src/krb5_plugin/sssd_krb5_locator_plugin.c b/src/krb5_plugin/sssd_krb5_locator_plugin.c index 3eced04..b8d4e31 100644 --- a/src/krb5_plugin/sssd_krb5_locator_plugin.c +++ b/src/krb5_plugin/sssd_krb5_locator_plugin.c @@ -86,7 +86,6 @@ static int get_krb5info(const char *realm, struct sssd_ctx *ctx, char *krb5info_name = NULL; size_t len; uint8_t buf[BUFSIZE + 1]; - uint8_t *p; int fd = -1; const char *name_tmpl = NULL; char *port_str; @@ -129,23 +128,19 @@ static int get_krb5info(const char *realm, struct sssd_ctx *ctx, goto done; } - len = BUFSIZE; - p = buf; memset(buf, 0, BUFSIZE+1); - while (len != 0 && (ret = read(fd, p, len)) != 0) { - if (ret == -1) { - if (errno == EINTR || errno == EAGAIN) continue; - PLUGIN_DEBUG(("read failed [%d][%s].\n", errno, strerror(errno))); - close(fd); - goto done; - } - len -= ret; - p += ret; + errno = 0; + len = sss_atomic_read_s(fd, buf, BUFSIZE); + if (len == -1) { + ret = errno; + PLUGIN_DEBUG(("read failed [%d][%s].\n", ret, strerror(ret))); + close(fd); + goto done; } close(fd); - if (len == 0) { + if (len == BUFSIZE) { PLUGIN_DEBUG(("Content of krb5info file [%s] is [%d] or larger.\n", krb5info_name, BUFSIZE)); } @@ -212,6 +207,7 @@ static int get_krb5info(const char *realm, struct sssd_ctx *ctx, goto done; } + ret = 0; done: free(krb5info_name); return ret; diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index cadc27f..041f576 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -1498,11 +1498,12 @@ static void process_config_file(struct tevent_context *ev, struct inotify_event *in_event; char *buf; char *name; - ssize_t len, total_len; + ssize_t len; ssize_t event_size; struct config_file_ctx *file_ctx; struct config_file_callback *cb; struct rewatch_ctx *rw_ctx; + errno_t ret; event_size = sizeof(struct inotify_event); file_ctx = talloc_get_type(ptr, struct config_file_ctx); @@ -1517,16 +1518,14 @@ static void process_config_file(struct tevent_context *ev, goto done; } - total_len = 0; - while (total_len < event_size) { - len = read(file_ctx->mt_ctx->inotify_fd, buf+total_len, - event_size-total_len); - if (len == -1) { - if (errno == EINTR || errno == EAGAIN) continue; - DEBUG(0, ("Critical error reading inotify file descriptor.\n")); - goto done; - } - total_len += len; + errno = 0; + len = sss_atomic_read_s(file_ctx->mt_ctx->inotify_fd, buf, event_size); + if (len == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("Critical error reading inotify file descriptor [%d]: %s\n", + ret, strerror(ret))); + goto done; } in_event = (struct inotify_event *)buf; @@ -1535,19 +1534,19 @@ static void process_config_file(struct tevent_context *ev, /* Read in the name, even though we don't use it, * so that read ptr is in the right place */ - name = talloc_size(tmp_ctx, len); + name = talloc_size(tmp_ctx, in_event->len); if (!name) { goto done; } - total_len = 0; - while (total_len < in_event->len) { - len = read(file_ctx->mt_ctx->inotify_fd, &name, in_event->len); - if (len == -1) { - if (errno == EINTR || errno == EAGAIN) continue; - DEBUG(0, ("Critical error reading inotify file descriptor.\n")); - goto done; - } - total_len += len; + + errno = 0; + len = sss_atomic_read_s(file_ctx->mt_ctx->inotify_fd, name, in_event->len); + if (len == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("Critical error reading inotify file descriptor [%d]: %s\n", + ret, strerror(ret))); + goto done; } } diff --git a/src/monitor/monitor_netlink.c b/src/monitor/monitor_netlink.c index 2fe380a..3842c4f 100644 --- a/src/monitor/monitor_netlink.c +++ b/src/monitor/monitor_netlink.c @@ -153,19 +153,17 @@ static bool has_ethernet_encapsulation(const char *sysfs_path) } memset(buf, 0, BUFSIZE); - while ((ret = read(fd, buf, BUFSIZE)) != 0) { - if (ret == -1) { - ret = errno; - if (ret == EINTR || ret == EAGAIN) { - continue; - } - DEBUG(SSSDBG_OP_FAILURE, - ("read failed [%d][%s].\n", ret, strerror(ret))); - close(fd); - return false; - } + errno = 0; + ret = sss_atomic_read_s(fd, buf, BUFSIZE); + if (ret == -1) { + ret = errno; + DEBUG(SSSDBG_OP_FAILURE, + ("read failed [%d][%s].\n", ret, strerror(ret))); + close(fd); + return false; } close(fd); + buf[BUFSIZE-1] = '\0'; return strncmp(buf, "1\n", BUFSIZE) == 0; } diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c index 209643a..cc29c00 100644 --- a/src/providers/krb5/krb5_child.c +++ b/src/providers/krb5/krb5_child.c @@ -461,18 +461,20 @@ static errno_t sendresponse(int fd, krb5_error_code kerr, int pam_status, return ENOMEM; } - written = 0; - while (written < resp->size) { - ret = write(fd, resp->buf + written, resp->size - written); - if (ret == -1) { - if (errno == EAGAIN || errno == EINTR) { - continue; - } - ret = errno; - DEBUG(1, ("write failed [%d][%s].\n", ret, strerror(ret))); - return ret; - } - written += ret; + errno = 0; + written = sss_atomic_write_s(fd, resp->buf, resp->size); + if (written == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("write failed [%d][%s].\n", ret, strerror(ret))); + return ret; + } + + if (written != resp->size) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Write error, wrote [%d] bytes, expected [%d]\n", + written, resp->size)); + return EOK; } return EOK; @@ -1631,25 +1633,14 @@ int main(int argc, const char *argv[]) goto fail; } - while ((ret = read(STDIN_FILENO, buf + len, IN_BUF_SIZE - len)) != 0) { - if (ret == -1) { - if (errno == EINTR || errno == EAGAIN) { - continue; - } - DEBUG(1, ("read failed [%d][%s].\n", errno, strerror(errno))); - goto fail; - } else if (ret > 0) { - len += ret; - if (len > IN_BUF_SIZE) { - DEBUG(1, ("read too much, this should never happen.\n")); - goto fail; - } - continue; - } else { - DEBUG(1, ("unexpected return code of read [%d].\n", ret)); - goto fail; - } + errno = 0; + len = sss_atomic_read_s(STDIN_FILENO, buf, IN_BUF_SIZE); + if (len == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, ("read failed [%d][%s].\n", ret, strerror(ret))); + goto fail; } + close(STDIN_FILENO); kr = talloc_zero(pd, struct krb5_req); diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c index d33900f..022745d 100644 --- a/src/providers/krb5/krb5_common.c +++ b/src/providers/krb5/krb5_common.c @@ -321,25 +321,19 @@ errno_t write_krb5info_file(const char *realm, const char *server, 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; - } - ret = errno; - DEBUG(1, ("write failed [%d][%s].\n", ret, strerror(ret))); - goto done; - } - else { - written += ret; - } + errno = 0; + written = sss_atomic_write_s(fd, discard_const(server), server_len); + if (written == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("write failed [%d][%s].\n", ret, strerror(ret))); + goto done; } if (written != server_len) { - DEBUG(1, ("Write error, wrote [%d] bytes, expected [%d]\n", - written, server_len)); + DEBUG(SSSDBG_CRIT_FAILURE, + ("Write error, wrote [%d] bytes, expected [%d]\n", + written, server_len)); ret = EIO; goto done; } diff --git a/src/providers/ldap/ldap_child.c b/src/providers/ldap/ldap_child.c index e66406c..5356f88 100644 --- a/src/providers/ldap/ldap_child.c +++ b/src/providers/ldap/ldap_child.c @@ -446,25 +446,14 @@ int main(int argc, const char *argv[]) goto fail; } - while ((ret = read(STDIN_FILENO, buf + len, IN_BUF_SIZE - len)) != 0) { - if (ret == -1) { - if (errno == EINTR || errno == EAGAIN) { - continue; - } - DEBUG(1, ("read failed [%d][%s].\n", errno, strerror(errno))); - goto fail; - } else if (ret > 0) { - len += ret; - if (len > IN_BUF_SIZE) { - DEBUG(1, ("read too much, this should never happen.\n")); - goto fail; - } - continue; - } else { - DEBUG(1, ("unexpected return code of read [%d].\n", ret)); - goto fail; - } + errno = 0; + len = sss_atomic_read_s(STDIN_FILENO, buf, IN_BUF_SIZE); + if (len == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, ("read failed [%d][%s].\n", ret, strerror(ret))); + goto fail; } + close(STDIN_FILENO); ret = unpack_buffer(buf, len, ibuf); @@ -484,22 +473,22 @@ int main(int argc, const char *argv[]) ret = prepare_response(main_ctx, ccname, expire_time, kerr, &resp); if (ret != EOK) { - DEBUG(1, ("prepare_response failed. [%d][%s].\n", ret, strerror(ret))); - return ENOMEM; + DEBUG(SSSDBG_CRIT_FAILURE, ("prepare_response failed. [%d][%s].\n", ret, strerror(ret))); + goto fail; } - written = 0; - while (written < resp->size) { - ret = write(STDOUT_FILENO, resp->buf + written, resp->size - written); - if (ret == -1) { - if (errno == EAGAIN || errno == EINTR) { - continue; - } - ret = errno; - DEBUG(1, ("write failed [%d][%s].\n", ret, strerror(ret))); - return ret; - } - written += ret; + errno = 0; + written = sss_atomic_write_s(STDOUT_FILENO, resp->buf, resp->size); + if (written == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, ("write failed [%d][%s].\n", ret, strerror(ret))); + goto fail; + } + + if (written != resp->size) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Expected to write %d bytes, wrote %d\n", + resp->size, written)); + goto fail; } close(STDOUT_FILENO); diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c index 7a7a498..e60d061 100644 --- a/src/responder/nss/nsssrv_mmap_cache.c +++ b/src/responder/nss/nsssrv_mmap_cache.c @@ -512,16 +512,16 @@ static errno_t sss_mc_set_recycled(int fd) /* What do we do now ? */ return errno; } - pos = 0; - while (pos < sizeof(h.status)) { - ret = write(fd, ((uint8_t *)&w) + pos, sizeof(h.status) - pos); - if (ret == -1) { - if (errno != EINTR) { - return errno; - } - continue; - } - pos += ret; + + errno = 0; + ret = sss_atomic_write_s(fd, (uint8_t *)&w, sizeof(h.status)); + if (ret == -1) { + return errno; + } + + if (ret != sizeof(h.status)) { + /* Write error */ + return EIO; } return EOK; diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c index 4882bac..1491370 100644 --- a/src/responder/ssh/sshsrv_cmd.c +++ b/src/responder/ssh/sshsrv_cmd.c @@ -516,7 +516,7 @@ ssh_host_pubkeys_update_known_hosts(struct ssh_cmd_ctx *cmd_ctx) goto done; } - wret = sss_atomic_write(fd, line, strlen(line)); + wret = sss_atomic_write_s(fd, line, strlen(line)); if (wret == -1) { ret = errno; goto done; diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c index 8778fe1..3de810c 100644 --- a/src/sss_client/pam_sss.c +++ b/src/sss_client/pam_sss.c @@ -47,6 +47,7 @@ #include "sss_pam_macros.h" #include "sss_cli.h" +#include "util/atomic_io.h" #include #define _(STRING) dgettext (PACKAGE, STRING) @@ -499,17 +500,12 @@ static errno_t display_pw_reset_message(pam_handle_t *pamh, goto done; } - - total_len = 0; - while (total_len < stat_buf.st_size) { - ret = read(fd, msg_buf + total_len, stat_buf.st_size - total_len); - if (ret == -1) { - if (errno == EINTR || errno == EAGAIN) continue; - ret = errno; - D(("read failed [%d][%s].", ret, strerror(ret))); - goto done; - } - total_len += ret; + errno = 0; + total_len = sss_atomic_read_s(fd, msg_buf, stat_buf.st_size); + if (ret == -1) { + ret = errno; + D(("read failed [%d][%s].", ret, strerror(ret))); + goto done; } ret = close(fd); @@ -1088,7 +1084,8 @@ static int send_and_receive(pam_handle_t *pamh, struct pam_items *pi, #ifdef HAVE_SELINUX char *path = NULL; char *tmp_path = NULL; - int pos, len; + ssize_t written; + int len; int fd; mode_t oldmask; #endif /* HAVE_SELINUX */ @@ -1206,21 +1203,24 @@ static int send_and_receive(pam_handle_t *pamh, struct pam_items *pi, goto done; } - pos = 0; len = strlen(pi->selinux_user); - while (pos < len) { - ret = write(fd, pi->selinux_user + pos, len-pos); - if (ret < 0) { - if (errno != EINTR) { - logger(pamh, LOG_ERR, "writing to SELinux data file " - "failed. %s", tmp_path); - pam_status = PAM_SYSTEM_ERR; - goto done; - } - continue; - } - pos += ret; + + errno = 0; + written = sss_atomic_write_s(fd, pi->selinux_user, len); + if (written == -1) { + ret = errno; + logger(pamh, LOG_ERR, "writing to SELinux data file " + "failed. %s", tmp_path); + pam_status = PAM_SYSTEM_ERR; + goto done; } + + if (written != len) { + logger(pamh, LOG_ERR, "Expected to write %d bytes, wrote %d", + written, len); + goto done; + } + close(fd); rename(tmp_path, path); diff --git a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c index 6424d7b..e45ef45 100644 --- a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c +++ b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c @@ -140,11 +140,11 @@ connect_socket(int family, struct sockaddr *addr, size_t addr_len) } errno = 0; - res = sss_atomic_write(i == 0 ? sock : 1, buffer, res); + res = sss_atomic_write_s(i == 0 ? sock : 1, buffer, res); ret = errno; if (res == -1) { DEBUG(SSSDBG_OP_FAILURE, - ("sss_atomic_write() failed (%d): %s\n", + ("sss_atomic_write_s() failed (%d): %s\n", ret, strerror(ret))); goto done; } else if (ret == EPIPE) { diff --git a/src/tools/files.c b/src/tools/files.c index 6947535..d80e3bd 100644 --- a/src/tools/files.c +++ b/src/tools/files.c @@ -411,7 +411,7 @@ static int copy_file(const char *src, int ifd = -1; int ofd = -1; char buf[1024]; - ssize_t cnt, written, res; + ssize_t cnt, written; struct stat fstatbuf; ifd = open(src, O_RDONLY); @@ -463,41 +463,28 @@ static int copy_file(const char *src, goto fail; } - while ((cnt = read(ifd, buf, sizeof(buf))) != 0) { + while ((cnt = sss_atomic_read_s(ifd, buf, sizeof(buf))) != 0) { if (cnt == -1) { - if (errno == EINTR || errno == EAGAIN) { - continue; - } - - DEBUG(1, ("Cannot read() from source file '%s': [%d][%s].\n", - src, ret, strerror(ret))); + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("Cannot read() from source file '%s': [%d][%s].\n", + src, ret, strerror(ret))); goto fail; } - else if (cnt > 0) { - /* Copy the buffer to the new file */ - written = 0; - while (written < cnt) { - res = write(ofd, buf+written, (size_t)cnt-written); - if (res == -1) { - ret = errno; - if (ret == EINTR || ret == EAGAIN) { - /* retry the write */ - continue; - } - DEBUG(1, ("Cannot write() to destination file '%s': [%d][%s].\n", - dst, ret, strerror(ret))); - goto fail; - } - else if (res <= 0) { - DEBUG(1, ("Unexpected result from write(): [%d]\n", res)); - goto fail; - } - - written += res; - } + + errno = 0; + written = sss_atomic_write_s(ofd, buf, cnt); + if (written == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("Cannot write() to destination file '%s': [%d][%s].\n", + dst, ret, strerror(ret))); + goto fail; } - else { - DEBUG(1, ("Unexpected return code of read [%d]\n", cnt)); + + if (written != cnt) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Wrote %d bytes, expected %d\n", written, cnt)); goto fail; } } diff --git a/src/util/backup_file.c b/src/util/backup_file.c index ba77640..edbf868 100644 --- a/src/util/backup_file.c +++ b/src/util/backup_file.c @@ -33,9 +33,8 @@ int backup_file(const char *src_file, int dbglvl) int src_fd = -1; int dst_fd = -1; char *dst_file; - ssize_t count; - ssize_t num; - ssize_t pos; + ssize_t numread; + ssize_t written; int ret, i; src_fd = open(src_file, O_RDONLY); @@ -84,31 +83,30 @@ int backup_file(const char *src_file, int dbglvl) /* copy file contents */ while (1) { - num = read(src_fd, buf, BUFFER_SIZE); - if (num < 0) { - if (errno == EINTR || errno == EAGAIN) continue; + errno = 0; + numread = sss_atomic_read_s(src_fd, buf, BUFFER_SIZE); + if (numread < 0) { ret = errno; DEBUG(dbglvl, ("Error (%d [%s]) reading from source %s\n", ret, strerror(ret), src_file)); goto done; } - if (num == 0) break; - - count = num; - - pos = 0; - while (count > 0) { - errno = 0; - num = write(dst_fd, &buf[pos], count); - if (num < 0) { - if (errno == EINTR || errno == EAGAIN) continue; - ret = errno; - DEBUG(dbglvl, ("Error (%d [%s]) writing to destination %s\n", - ret, strerror(ret), dst_file)); - goto done; - } - pos += num; - count -= num; + if (numread == 0) break; + + errno = 0; + written = sss_atomic_write_s(dst_fd, buf, numread); + if (written == -1) { + ret = errno; + DEBUG(dbglvl, ("Error (%d [%s]) writing to destination %s\n", + ret, strerror(ret), dst_file)); + goto done; + } + + if (written != numread) { + DEBUG(dbglvl, ("Wrote %d bytes expected %d bytes\n", + written, numread)); + ret = EIO; + goto done; } } diff --git a/src/util/child_common.c b/src/util/child_common.c index 6214c7c..05f00b0 100644 --- a/src/util/child_common.c +++ b/src/util/child_common.c @@ -337,42 +337,36 @@ static void write_pipe_handler(struct tevent_context *ev, struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct write_pipe_state *state = tevent_req_data(req, struct write_pipe_state); - ssize_t size; + errno_t ret; if (flags & TEVENT_FD_READ) { - DEBUG(1, ("write_pipe_done called with TEVENT_FD_READ," - " this should not happen.\n")); + DEBUG(SSSDBG_CRIT_FAILURE, + ("write_pipe_done called with TEVENT_FD_READ," + " this should not happen.\n")); tevent_req_error(req, EINVAL); return; } - size = write(state->fd, - state->buf + state->written, - state->len - state->written); - if (size == -1) { - if (errno == EAGAIN || errno == EINTR) return; - DEBUG(1, ("write failed [%d][%s].\n", errno, strerror(errno))); - tevent_req_error(req, errno); - return; - - } else if (size >= 0) { - state->written += size; - if (state->written > state->len) { - DEBUG(1, ("write to much, this should never happen.\n")); - tevent_req_error(req, EINVAL); - return; - } - } else { - DEBUG(1, ("unexpected return value of write [%d].\n", size)); - tevent_req_error(req, EINVAL); + errno = 0; + state->written = sss_atomic_write_s(state->fd, state->buf, state->len); + if (state->written == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("write failed [%d][%s].\n", ret, strerror(ret))); + tevent_req_error(req, ret); return; } - if (state->len == state->written) { - DEBUG(6, ("All data has been sent!\n")); - tevent_req_done(req); + if (state->len != state->written) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Wrote %d bytes, expected %d\n", + state->written, state->len)); + tevent_req_error(req, EIO); return; } + + DEBUG(SSSDBG_TRACE_FUNC, ("All data has been sent!\n")); + tevent_req_done(req); + return; } int write_pipe_recv(struct tevent_req *req) @@ -438,16 +432,13 @@ static void read_pipe_handler(struct tevent_context *ev, return; } - size = read(state->fd, + size = sss_atomic_read_s(state->fd, buf, CHILD_MSG_CHUNK); if (size == -1) { err = errno; - if (err == EAGAIN || err == EINTR) { - return; - } - - DEBUG(1, ("read failed [%d][%s].\n", err, strerror(err))); + DEBUG(SSSDBG_CRIT_FAILURE, + ("read failed [%d][%s].\n", err, strerror(err))); tevent_req_error(req, err); return; diff --git a/src/util/find_uid.c b/src/util/find_uid.c index 77b9f22..d34a4ab 100644 --- a/src/util/find_uid.c +++ b/src/util/find_uid.c @@ -107,15 +107,13 @@ static errno_t get_uid_from_pid(const pid_t pid, uid_t *uid) goto fail_fd; } - while ((ret = read(fd, buf, BUFSIZE)) != 0) { - if (ret == -1) { - error = errno; - if (error == EINTR || error == EAGAIN) { - continue; - } - DEBUG(1, ("read failed [%d][%s].\n", error, strerror(error))); - goto fail_fd; - } + errno = 0; + ret = sss_atomic_read_s(fd, buf, BUFSIZE); + if (ret == -1) { + error = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("read failed [%d][%s].\n", error, strerror(error))); + goto fail_fd; } /* Guarantee NULL-termination in case we read the full BUFSIZE somehow */ diff --git a/src/util/server.c b/src/util/server.c index 95b1836..39cc127 100644 --- a/src/util/server.c +++ b/src/util/server.c @@ -117,51 +117,36 @@ int pidfile(const char *path, const char *name) fd = open(file, O_RDONLY, 0644); err = errno; if (fd != -1) { - len = 0; - while ((ret = read(fd, pid_str + len, pidlen - len)) != 0) { - if (ret == -1) { - if (errno == EINTR || errno == EAGAIN) { - continue; - } - DEBUG(1, ("read failed [%d][%s].\n", errno, strerror(errno))); - break; - } else if (ret > 0) { - len += ret; - if (len > pidlen) { - DEBUG(1, ("read too much, this should never happen.\n")); - close(fd); - talloc_free(file); - return EINVAL; - } - continue; - } else { - DEBUG(1, ("unexpected return code of read [%d].\n", ret)); - break; - } + errno = 0; + len = sss_atomic_read_s(fd, pid_str, pidlen); + ret = errno; + if (len == -1) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("read failed [%d][%s].\n", ret, strerror(ret))); + close(fd); + talloc_free(file); + return EINVAL; } /* Ensure NULL-termination */ pid_str[len] = '\0'; - if (ret == 0) { - /* let's check the pid */ - - pid = (pid_t)atoi(pid_str); - if (pid != 0) { - errno = 0; - ret = kill(pid, 0); - /* succeeded in signaling the process -> another sssd process */ - if (ret == 0) { - close(fd); - talloc_free(file); - return EEXIST; - } - if (ret != 0 && errno != ESRCH) { - err = errno; - close(fd); - talloc_free(file); - return err; - } + /* let's check the pid */ + pid = (pid_t)atoi(pid_str); + if (pid != 0) { + errno = 0; + ret = kill(pid, 0); + /* succeeded in signaling the process -> another sssd process */ + if (ret == 0) { + close(fd); + talloc_free(file); + return EEXIST; + } + if (ret != 0 && errno != ESRCH) { + err = errno; + close(fd); + talloc_free(file); + return err; } } @@ -188,25 +173,20 @@ int pidfile(const char *path, const char *name) snprintf(pid_str, sizeof(pid_str) -1, "%u\n", (unsigned int) getpid()); size = strlen(pid_str); - written = 0; - while (written < size) { - ret = write(fd, pid_str+written, size-written); - if (ret == -1) { - err = errno; - if (err == EINTR || err == EAGAIN) { - continue; - } - DEBUG(1, ("write failed [%d][%s]\n", err, strerror(err))); - break; - } - else { - written += ret; - } + errno = 0; + written = sss_atomic_write_s(fd, pid_str, size); + if (ret == -1) { + err = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("write failed [%d][%s]\n", err, strerror(err))); + return err; } if (written != size) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Wrote %d bytes expected %d\n", written, size)); close(fd); - return err; + return EIO; } close(fd); @@ -317,8 +297,10 @@ static void server_stdin_handler(struct tevent_context *event_ctx, { const char *binary_name = (const char *)private; uint8_t c; - if (read(0, &c, 1) == 0) { - DEBUG(0,("%s: EOF on stdin - terminating\n", binary_name)); + + errno = 0; + if (sss_atomic_read_s(0, &c, 1) == 0) { + DEBUG(SSSDBG_CRIT_FAILURE,("%s: EOF on stdin - terminating\n", binary_name)); #if HAVE_GETPGRP if (getpgrp() == getpid()) { kill(-getpgrp(), SIGTERM);