File: io.c

package info (click to toggle)
socket 1.1-10
  • links: PTS
  • area: main
  • in suites: buster, jessie, jessie-kfreebsd, squeeze, stretch, wheezy
  • size: 128 kB
  • ctags: 81
  • sloc: ansic: 947; makefile: 159; sh: 18
file content (139 lines) | stat: -rw-r--r-- 3,220 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*

$Header: io.c[1.10] Sun Aug 30 19:21:18 1992 nickel@cs.tu-berlin.de proposed $
This file is part of socket(1).
Copyright (C) 1992 by Juergen Nickelsen <nickel@cs.tu-berlin.de>
Please read the file COPYRIGHT for further details.

*/

#define _BSD			/* AIX *loves* this */

#ifdef __linux__
#include <unistd.h>
#include <string.h>
#endif
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#ifdef ISC
#include <sys/bsdtypes.h>
#endif
#include <errno.h>
#include <stdio.h>
#include "globals.h"

/* read from from, write to to. select(2) has returned, so input
 * must be available. */
int do_read_write(from, to)
int from, to ;
{
    int size ;
    char input_buffer[BUFSIZ] ;
    
    if ((size = read(from, input_buffer, BUFSIZ)) == -1) {
	perror2("read") ;
	return -1 ;
    }
    if (size == 0) {		/* end-of-file condition */
	if (from == active_socket) {
	    /* if it was the socket, the connection is closed */
	    if (verboseflag) {
		fprintf(stderr, "connection closed by peer\n") ;
	    }
	    return -1 ;
	} else {
	    if (quitflag) {
		/* we close connection later */
		if (verboseflag) {
		    fprintf(stderr, "connection closed\n") ;
		}
		return -1 ;
	    } else if (verboseflag) {
		fprintf(stderr, "end of input on stdin\n") ;
	    }
	    readonlyflag = 1 ;
	    return 1 ;
	}
    }
    return do_write(input_buffer, size, to) ;

}

/* write the buffer; in successive pieces, if necessary. */
int do_write(buffer, size, to)
char *buffer ;
int size, to ;
{
    char buffer2[2 * BUFSIZ] ;	/* expanding lf's to crlf's can
				 * make the block twice as big at most */
    int written ;

    if (crlfflag) {
	if (to == active_socket) {
	    add_crs(buffer, buffer2, &size) ;
	} else {
	    strip_crs(buffer, buffer2, &size) ;
	}
    // debfix } else {
	// debfix bcopy(buffer, buffer2, size) ;
	buffer = buffer2 ;
    }
    while (size > 0) {
	// written = write(to, buffer2, size) ;
	written = write(to, buffer, size) ;
	if (written == -1) {
	    /* this should not happen */
	    perror2("write") ;
	    fprintf(stderr, "%s: error writing to %s\n",
		    progname,
		    to == active_socket ? "socket" : "stdout") ;
	    return -1 ;
	}
	size -= written ;
	buffer += written ;
    }
    return 1 ;
}

/* all IO to and from the socket is handled here. The main part is
 * a loop around select(2). */
void do_io()
{
    fd_set readfds ;
    int fdset_width ;
    int selret ;

    fdset_width = (IN > active_socket ? IN : active_socket) + 1 ;
    while (1) {			/* this loop is exited sideways */
	/* set up file descriptor set for select(2) */
	FD_ZERO(&readfds) ;
	if (!readonlyflag) {
	    FD_SET(IN, &readfds) ;
	}
	if (!writeonlyflag) {
	    FD_SET(active_socket, &readfds) ;
	}

	do {
	    /* wait until input is available */
	    selret = select(fdset_width, &readfds, NULL, NULL, NULL) ;
	    /* EINTR happens when the process is stopped */
	    if (selret < 0 && errno != EINTR) {
		perror2("select") ;
		exit(1) ;
	    }
	} while (selret <= 0) ;

	/* do the appropriate read and write */
	if (FD_ISSET(active_socket, &readfds)) {
	    if (do_read_write(active_socket, OUT) < 0) {
		break ;
	    }
	} else {
	    if (do_read_write(IN, active_socket) < 0) {
		break ;
	    }
	}
    }
}