|
40 |
#include <wait.h> |
40 |
#include <wait.h> |
41 |
#include <errno.h> |
41 |
#include <errno.h> |
42 |
#include <string.h> |
42 |
#include <string.h> |
|
|
43 |
#include <fcntl.h> |
43 |
|
44 |
|
44 |
extern int errno; |
45 |
extern int errno; |
45 |
|
46 |
|
|
71 |
return 0; |
72 |
return 0; |
72 |
} |
73 |
} |
73 |
|
74 |
|
|
|
75 |
/* |
76 |
* Move file descriptor and mark as CLOSE-ON-EXEC. |
77 |
*/ |
78 |
static int move_fd(int oldfd, int newfd) { |
79 |
int flags; |
80 |
int tmpfd; |
81 |
|
82 |
if (oldfd != newfd) |
83 |
tmpfd = dup2(oldfd, newfd); |
84 |
else |
85 |
tmpfd = newfd; |
86 |
if (tmpfd != newfd) |
87 |
fatal_perror("Error dup2 failed\n"); |
88 |
flags = fcntl(tmpfd, F_GETFD); |
89 |
if (flags == -1) |
90 |
fatal_perror("Error getting tmpfd status\n"); |
91 |
flags |= FD_CLOEXEC; |
92 |
if (fcntl(tmpfd, F_SETFD, flags) == -1) |
93 |
fatal_perror("Error setting tmpfd status\n"); |
94 |
|
95 |
return tmpfd; |
96 |
} |
97 |
|
98 |
/* |
99 |
* Open /dev/null on fd in mode given by flags. |
100 |
*/ |
101 |
static void open_dev_null(int fd, int flags) { |
102 |
int tmpfd; |
103 |
|
104 |
close(fd); /* ignore error if already closed. */ |
105 |
tmpfd = open("/dev/null", flags); |
106 |
if (tmpfd < 0) |
107 |
fatal_perror("Error opening /dev/null\n"); |
108 |
if (tmpfd != fd) { |
109 |
int ret; |
110 |
|
111 |
ret = dup2(tmpfd, fd); |
112 |
if (ret < 0) |
113 |
fatal_perror("Error dup2 failed\n"); |
114 |
ret = close(tmpfd); |
115 |
if (ret < 0) |
116 |
fatal_perror("Error closing fd\n"); |
117 |
} |
118 |
} |
119 |
|
120 |
/* |
121 |
* Clone FDs for client<->server communication inherited from SESSION_RSH |
122 |
* to private FDs and mark them as CLOSE-ON-EXEC. |
123 |
* Re-open STDIN and STDOUT as /dev/null to protect channel from non-protocol |
124 |
* data. STDERR uses a separate channel and needs not to be changed; keep it |
125 |
* for debugging. |
126 |
* |
127 |
* FD 3 and 4 are used to not mix with STDIN=0, STDOUT=1 and STDERR=2. |
128 |
* Don't use dup() after closing previous FDs with close()! |
129 |
*/ |
74 |
void init_server_pipes ( void ) |
130 |
void init_server_pipes ( void ) |
75 |
{ |
131 |
{ |
76 |
/* FIXME: what is fd 3? maybe use dup() instead */ |
132 |
send_fd = move_fd(STDOUT_FILENO, 3); |
77 |
send_fd = dup2 ( STDOUT_FILENO, 3 ); |
|
|
78 |
if ( send_fd < 0 ) |
79 |
fatal_perror ( "dup failed" ); |
80 |
close ( STDOUT_FILENO ); |
81 |
if ( debug_level ) |
133 |
if ( debug_level ) |
82 |
debug_printf ( "to_client fd=%d\n", send_fd ); |
134 |
debug_printf ( "to_client fd=%d\n", send_fd ); |
83 |
/* FIXME: see above */ |
135 |
open_dev_null(STDOUT_FILENO, O_WRONLY); |
84 |
recv_fd = dup2 ( STDIN_FILENO, 4); |
136 |
|
85 |
if ( recv_fd < 0 ) |
137 |
recv_fd = move_fd(STDIN_FILENO, 4); |
86 |
fatal_perror ( "dup failed" ); |
|
|
87 |
close ( STDIN_FILENO ); |
88 |
add_read_fd ( recv_fd, connection_read_handler ); |
138 |
add_read_fd ( recv_fd, connection_read_handler ); |
89 |
if ( debug_level ) |
139 |
if ( debug_level ) |
90 |
debug_printf ( "from_client fd=%d\n", recv_fd ); |
140 |
debug_printf ( "from_client fd=%d\n", recv_fd ); |
|
|
141 |
open_dev_null(STDIN_FILENO, O_RDONLY); |
142 |
|
91 |
return; |
143 |
return; |
92 |
} |
144 |
} |
93 |
|
145 |
|