intptr_t omrfile_write(struct OMRPortLibrary *portLibrary, intptr_t fd, const void *buf, intptr_t nbytes) { DWORD nCharsWritten; intptr_t toWrite, offset = 0; int32_t errorCode; HANDLE handle; Trc_PRT_file_write_Entry(fd, buf, nbytes); if (OMRPORT_TTY_OUT == fd) { handle = PPG_tty_consoleOutputHd; } else if (OMRPORT_TTY_ERR == fd) { handle = PPG_tty_consoleErrorHd; } else { handle = (HANDLE)fd; } toWrite = nbytes; while (nbytes > 0) { if (toWrite > nbytes) { toWrite = nbytes; } /* The (DWORD)nbytes downcasts can make toWrite smaller than nbytes, however, the while loop * ensures that nbytes of data is still written */ if (FALSE == WriteFile(handle, (char *)buf + offset, (DWORD)toWrite, &nCharsWritten, NULL)) { errorCode = GetLastError(); if (ERROR_NOT_ENOUGH_MEMORY == errorCode) { /*[PR 94924] Use 48K chunks to get around out of memory problem */ if (toWrite > (48 * 1024)) { toWrite = 48 * 1024; } else { toWrite /= 2; } /* If we can't write 128 bytes, just return */ if (toWrite >= 128) { continue; } } errorCode = portLibrary->error_set_last_error(portLibrary, errorCode, findError(errorCode)); Trc_PRT_file_write_Exit(errorCode); return errorCode; } offset += nCharsWritten; nbytes -= nCharsWritten; } Trc_PRT_file_write_Exit(offset); return offset; }
/** * Write to a file. * * Writes up to nbytes from the provided buffer to the file referenced by the file descriptor. * * @param[in] portLibrary The port library * @param[in] fd File descriptor to write. * @param[in] buf Buffer to be written. * @param[in] nbytes Size of buffer. * * @return Number of bytes written on success, portable error return code (which is negative) on failure. */ intptr_t omrfile_write(struct OMRPortLibrary *portLibrary, intptr_t inFD, const void *buf, intptr_t nbytes) { int fd = (int)inFD; intptr_t rc; Trc_PRT_file_write_Entry(fd, buf, nbytes); #ifdef AIXPPC /* Avoid hang on AIX when calling write() with 0 bytes on standard streams. */ if ((0 == nbytes) && ((fd == OMRPORT_TTY_OUT) || (fd == OMRPORT_TTY_ERR))) { Trc_PRT_file_write_Exit(0); return 0; } #endif #ifdef J9ZOS390 if (fd == OMRPORT_TTY_OUT) { rc = fwrite(buf, sizeof(char), nbytes, stdout); } else if (fd == OMRPORT_TTY_ERR) { rc = fwrite(buf, sizeof(char), nbytes, stderr); } else if (fd < FD_BIAS) { /* Cannot fsync STDIN, and no other FD's should exist <FD_BIAS */ Trc_PRT_file_write_Exit(-1); return -1; } else #elif (FD_BIAS != 0) #error FD_BIAS must be 0 #endif { /* CMVC 178203 - Restart system calls interrupted by EINTR */ do { /* write will just do the right thing for OMRPORT_TTY_OUT and OMRPORT_TTY_ERR */ rc = write(fd - FD_BIAS, buf, nbytes); } while ((-1 == rc) && (EINTR == errno)); } if (rc == -1) { rc = portLibrary->error_set_last_error(portLibrary, errno, findError(errno)); } Trc_PRT_file_write_Exit(rc); return rc; }