mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r6890: Refactor printing interface to take offset into job. Fixes bug
where large print jobs can have out-of-order offsets. Bug found
by Arcady Chernyak <Arcady.Chernyak@efi.com>
Jeremy.
(This used to be commit 482f7e0e37
)
This commit is contained in:
parent
3b0df6770d
commit
fe0ce8dd8e
@ -640,6 +640,46 @@ void close_low_fds(BOOL stderr_too)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Write data into an fd at a given offset. Ignore seek errors.
|
||||
********************************************************************/
|
||||
|
||||
ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
|
||||
{
|
||||
size_t total=0;
|
||||
ssize_t ret;
|
||||
|
||||
if (pos == (SMB_OFF_T)-1) {
|
||||
return write_data(fd, buffer, N);
|
||||
}
|
||||
#if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
|
||||
while (total < N) {
|
||||
ret = sys_pwrite(fd,buffer + total,N - total, pos);
|
||||
if (ret == -1 && errno == ESPIPE) {
|
||||
return write_data(fd, buffer + total,N - total);
|
||||
}
|
||||
if (ret == -1) {
|
||||
DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
|
||||
return -1;
|
||||
}
|
||||
if (ret == 0) {
|
||||
return total;
|
||||
}
|
||||
total += ret;
|
||||
pos += ret;
|
||||
}
|
||||
return (ssize_t)total;
|
||||
#else
|
||||
/* Use lseek and write_data. */
|
||||
if (sys_lseek(fd, pos, SEEK_SET) == -1) {
|
||||
if (errno != ESPIPE) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return write_data(fd, buffer, N);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
|
||||
else
|
||||
|
@ -403,7 +403,7 @@ static ssize_t read_socket_data(int fd,char *buffer,size_t N)
|
||||
Write data to a fd.
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t write_data(int fd,char *buffer,size_t N)
|
||||
ssize_t write_data(int fd, const char *buffer, size_t N)
|
||||
{
|
||||
size_t total=0;
|
||||
ssize_t ret;
|
||||
@ -427,7 +427,7 @@ ssize_t write_data(int fd,char *buffer,size_t N)
|
||||
Write data to a socket - use send rather than write.
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t write_socket_data(int fd,char *buffer,size_t N)
|
||||
static ssize_t write_socket_data(int fd, const char *buffer, size_t N)
|
||||
{
|
||||
size_t total=0;
|
||||
ssize_t ret;
|
||||
@ -451,7 +451,7 @@ static ssize_t write_socket_data(int fd,char *buffer,size_t N)
|
||||
Write to a socket.
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t write_socket(int fd,char *buf,size_t len)
|
||||
ssize_t write_socket(int fd, const char *buf, size_t len)
|
||||
{
|
||||
ssize_t ret=0;
|
||||
|
||||
@ -489,7 +489,7 @@ BOOL send_keepalive(int client)
|
||||
Timeout is in milliseconds.
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
|
||||
static ssize_t read_smb_length_return_keepalive(int fd, char *inbuf, unsigned int timeout)
|
||||
{
|
||||
ssize_t len=0;
|
||||
int msg_type;
|
||||
@ -523,7 +523,7 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int
|
||||
Timeout is in milliseconds.
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
|
||||
ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout)
|
||||
{
|
||||
ssize_t len;
|
||||
|
||||
@ -552,7 +552,7 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
|
||||
Doesn't check the MAC on signed packets.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout)
|
||||
BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout)
|
||||
{
|
||||
ssize_t len,ret;
|
||||
|
||||
@ -617,7 +617,7 @@ BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout)
|
||||
Checks the MAC on signed packets.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
|
||||
BOOL receive_smb(int fd, char *buffer, unsigned int timeout)
|
||||
{
|
||||
if (!receive_smb_raw(fd, buffer, timeout)) {
|
||||
return False;
|
||||
@ -638,7 +638,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
|
||||
Send an smb to a fd.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL send_smb(int fd,char *buffer)
|
||||
BOOL send_smb(int fd, char *buffer)
|
||||
{
|
||||
size_t len;
|
||||
size_t nwritten=0;
|
||||
|
@ -2031,7 +2031,7 @@ pause, or resume print job. User name: %s. Printer name: %s.",
|
||||
Write to a print file.
|
||||
****************************************************************************/
|
||||
|
||||
int print_job_write(int snum, uint32 jobid, const char *buf, int size)
|
||||
ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
|
||||
{
|
||||
const char* sharename = lp_const_servicename(snum);
|
||||
int return_code;
|
||||
@ -2045,7 +2045,8 @@ int print_job_write(int snum, uint32 jobid, const char *buf, int size)
|
||||
if (pjob->pid != sys_getpid())
|
||||
return -1;
|
||||
|
||||
return_code = write(pjob->fd, buf, size);
|
||||
return_code = write_data_at_offset(pjob->fd, buf, size, pos);
|
||||
|
||||
if (return_code>0) {
|
||||
pjob->size += size;
|
||||
pjob_store(sharename, jobid, pjob);
|
||||
|
@ -5798,8 +5798,9 @@ WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R
|
||||
if (!get_printer_snum(p, handle, &snum))
|
||||
return WERR_BADFID;
|
||||
|
||||
(*buffer_written) = print_job_write(snum, Printer->jobid, (char *)buffer, buffer_size);
|
||||
if (*buffer_written == -1) {
|
||||
(*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
|
||||
(SMB_OFF_T)-1, (size_t)buffer_size);
|
||||
if (*buffer_written == (uint32)-1) {
|
||||
r_u->buffer_written = 0;
|
||||
if (errno == ENOSPC)
|
||||
return WERR_NO_SPOOL_SPACE;
|
||||
|
@ -117,7 +117,7 @@ static unsigned int allocated_write_caches;
|
||||
*Really* write to a file.
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_t n)
|
||||
static ssize_t real_write_file(files_struct *fsp,const char *data, SMB_OFF_T pos, size_t n)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
@ -192,7 +192,7 @@ static int wcp_file_size_change(files_struct *fsp)
|
||||
Write to a file.
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
|
||||
ssize_t write_file(files_struct *fsp, const char *data, SMB_OFF_T pos, size_t n)
|
||||
{
|
||||
write_cache *wcp = fsp->wcp;
|
||||
ssize_t total_written = 0;
|
||||
@ -209,7 +209,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return print_job_write(SNUM(fsp->conn), jobid, data, n);
|
||||
return print_job_write(SNUM(fsp->conn), jobid, data, pos, n);
|
||||
}
|
||||
|
||||
if (!fsp->can_write) {
|
||||
|
Loading…
Reference in New Issue
Block a user