/* * UNIXReadWrite.h * * $Header: /cvs/kfm/Common/Sources/UNIXReadWrite.c,v 1.2 2004/12/13 21:51:15 lxs Exp $ * * Copyright 2004 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include <Kerberos/KerberosDebug.h> #include "UNIXReadWrite.h" #include <sys/types.h> #include <sys/uio.h> #include <unistd.h> #include <errno.h> #include <stdlib.h> static int __UNIXReadWriteError (int err, const char *function, const char *file, int line); #define URWError_(err) __UNIXReadWriteError(err, __FUNCTION__, __FILE__, __LINE__) // --------------------------------------------------------------------------- // Error reporting // --------------------------------------------------------------------------- static int __UNIXReadWriteError (int err, const char *function, const char *file, int line) { if (err && (ddebuglevel () > 0)) { dprintf ("%s() error %ld ('%s') at %s: %d", function, err, strerror (err), file, line); } return err; } // --------------------------------------------------------------------------- // Standard read loop, accounting for EINTR, EOF and incomplete reads // --------------------------------------------------------------------------- int ReadBuffer (int inDescriptor, size_t inBufferLength, char *ioBuffer) { int err = 0; size_t bytesRead = 0; if (ioBuffer == NULL) { err = EINVAL; } if (!err) { char *ptr = ioBuffer; do { ssize_t count = read (inDescriptor, ptr, inBufferLength - bytesRead); if (count < 0) { // Try again on EINTR if (errno != EINTR) { err = errno; } } else if (count == 0) { err = ECONNRESET; // EOF and we expected data } else { ptr += count; bytesRead += count; } } while (!err && (bytesRead < inBufferLength)); } return URWError_ (err); } // --------------------------------------------------------------------------- // Standard write loop, accounting for EINTR and incomplete writes // --------------------------------------------------------------------------- int WriteBuffer (int inDescriptor, const char *inBuffer, size_t inBufferLength) { int err = 0; size_t bytesWritten = 0; if (inBuffer == NULL) { err = EINVAL; } if (!err) { const char *ptr = inBuffer; do { ssize_t count = write (inDescriptor, ptr, inBufferLength - bytesWritten); if (count < 0) { // Try again on EINTR if (errno != EINTR) { err = errno; } } else { ptr += count; bytesWritten += count; } } while (!err && (bytesWritten < inBufferLength)); } return URWError_ (err); } // --------------------------------------------------------------------------- // Read a dynamic length buffer (length + data) off the descriptor // --------------------------------------------------------------------------- int ReadDynamicLengthBuffer (int inDescriptor, char **outData, size_t *outLength) { int err = 0; char *data = NULL; u_int32_t length = 0; if (outData == NULL) { err = EINVAL; } if (outLength == NULL) { err = EINVAL; } if (!err) { err = ReadBuffer (inDescriptor, 4, (char *) &length); } if (!err) { length = ntohl (length); } if (!err) { data = malloc (length); if (data == NULL) { err = ENOMEM; } } if (!err) { memset (data, 0, length); err = ReadBuffer (inDescriptor, length, data); } if (!err) { *outLength = length; *outData = data; data = NULL; // only free on error } if (data != NULL) { free (data); } return URWError_ (err); } // --------------------------------------------------------------------------- // Write a dynamic length buffer (length + data) to the descriptor // --------------------------------------------------------------------------- int WriteDynamicLengthBuffer (int inDescriptor, const char *inData, size_t inLength) { int err = 0; u_int32_t length = htonl (inLength); if (inData == NULL) { err = EINVAL; } if (!err) { err = WriteBuffer (inDescriptor, (char *) &length, 4); } if (!err) { err = WriteBuffer (inDescriptor, inData, inLength); } return URWError_ (err); }