Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Centralise calls to fcntl into functions that carefully check the error returns. |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
04c7a24906d70e921426a42cc6ef4734 |
| User & Date: | simon 2013-07-19 13:10:02.000 |
Context
|
2013-07-20
| ||
| 03:34 | Been meaning to get round to this for a while: use CryptGenRandom to gather extra entropy at Windows PuTTY startup time. (It's only used as one of the inputs to PuTTY's internal entropy pool, so nobody is required to trust it.) check-in: 47054fafef user: simon tags: trunk | |
|
2013-07-19
| ||
| 13:10 | Centralise calls to fcntl into functions that carefully check the error returns. check-in: 04c7a24906 user: simon tags: trunk | |
| 12:45 | Add an error check to every setsockopt call in uxnet.c. check-in: 9121a6c35f user: simon tags: trunk | |
Changes
Changes to unix/gtkwin.c.
| ︙ | ︙ | |||
3303 3304 3305 3306 3307 3308 3309 |
strcpy(data + p, pty_argv[i]);
p += strlen(pty_argv[i]) + 1;
}
assert(p == size);
}
sprintf(option, "---[%d,%d]", pipefd[0], size);
| | | 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 |
strcpy(data + p, pty_argv[i]);
p += strlen(pty_argv[i]) + 1;
}
assert(p == size);
}
sprintf(option, "---[%d,%d]", pipefd[0], size);
noncloexec(pipefd[0]);
fork_and_exec_self(inst, pipefd[1], option, NULL);
close(pipefd[0]);
i = ret = 0;
while (i < size && (ret = write(pipefd[1], data + i, size - i)) > 0)
i += ret;
if (ret < 0)
|
| ︙ | ︙ |
Changes to unix/unix.h.
| ︙ | ︙ | |||
152 153 154 155 156 157 158 | #define stricmp strcasecmp /* BSD-semantics version of signal(), and another helpful function */ void (*putty_signal(int sig, void (*func)(int)))(int); void block_signal(int sig, int block_it); /* uxmisc.c */ | | > > > | 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | #define stricmp strcasecmp /* BSD-semantics version of signal(), and another helpful function */ void (*putty_signal(int sig, void (*func)(int)))(int); void block_signal(int sig, int block_it); /* uxmisc.c */ void cloexec(int); void noncloexec(int); int nonblock(int); int no_nonblock(int); /* * Exports from unicode.c. */ struct unicode_data; int init_ucs(struct unicode_data *ucsdata, char *line_codepage, int utf8_override, int font_charset, int vtmode); |
| ︙ | ︙ |
Changes to unix/uxmisc.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /* * PuTTY miscellaneous Unix stuff */ #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <unistd.h> #include <time.h> #include <sys/time.h> #include <sys/types.h> #include <pwd.h> #include "putty.h" | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /* * PuTTY miscellaneous Unix stuff */ #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <errno.h> #include <unistd.h> #include <time.h> #include <sys/time.h> #include <sys/types.h> #include <pwd.h> #include "putty.h" |
| ︙ | ︙ | |||
164 165 166 167 168 169 170 | "PuTTY Master Key (RSA), 1024-bit:\n" " " PGP_RSA_MASTER_KEY_FP "\n" "PuTTY Master Key (DSA), 1024-bit:\n" " " PGP_DSA_MASTER_KEY_FP "\n", stdout); } /* | | > > > > > > > | | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
"PuTTY Master Key (RSA), 1024-bit:\n"
" " PGP_RSA_MASTER_KEY_FP "\n"
"PuTTY Master Key (DSA), 1024-bit:\n"
" " PGP_DSA_MASTER_KEY_FP "\n", stdout);
}
/*
* Set and clear fcntl options on a file descriptor. We don't
* realistically expect any of these operations to fail (the most
* plausible error condition is EBADF, but we always believe ourselves
* to be passing a valid fd so even that's an assertion-fail sort of
* response), so we don't make any effort to return sensible error
* codes to the caller - we just log to standard error and die
* unceremoniously. However, nonblock and no_nonblock do return the
* previous state of O_NONBLOCK.
*/
void cloexec(int fd) {
int fdflags;
fdflags = fcntl(fd, F_GETFD);
if (fdflags < 0) {
fprintf(stderr, "%d: fcntl(F_GETFD): %s\n", fd, strerror(errno));
exit(1);
}
if (fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC) < 0) {
fprintf(stderr, "%d: fcntl(F_SETFD): %s\n", fd, strerror(errno));
exit(1);
}
}
void noncloexec(int fd) {
int fdflags;
fdflags = fcntl(fd, F_GETFD);
if (fdflags < 0) {
fprintf(stderr, "%d: fcntl(F_GETFD): %s\n", fd, strerror(errno));
exit(1);
}
if (fcntl(fd, F_SETFD, fdflags & ~FD_CLOEXEC) < 0) {
fprintf(stderr, "%d: fcntl(F_SETFD): %s\n", fd, strerror(errno));
exit(1);
}
}
int nonblock(int fd) {
int fdflags;
fdflags = fcntl(fd, F_GETFL);
if (fdflags < 0) {
fprintf(stderr, "%d: fcntl(F_GETFL): %s\n", fd, strerror(errno));
exit(1);
}
if (fcntl(fd, F_SETFL, fdflags | O_NONBLOCK) < 0) {
fprintf(stderr, "%d: fcntl(F_SETFL): %s\n", fd, strerror(errno));
exit(1);
}
return fdflags & O_NONBLOCK;
}
int no_nonblock(int fd) {
int fdflags;
fdflags = fcntl(fd, F_GETFL);
if (fdflags < 0) {
fprintf(stderr, "%d: fcntl(F_GETFL): %s\n", fd, strerror(errno));
exit(1);
}
if (fcntl(fd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) {
fprintf(stderr, "%d: fcntl(F_SETFL): %s\n", fd, strerror(errno));
exit(1);
}
return fdflags & O_NONBLOCK;
}
FILE *f_open(const Filename *filename, char const *mode, int is_private)
{
if (!is_private) {
return fopen(filename->path, mode);
} else {
|
| ︙ | ︙ |
Changes to unix/uxnet.c.
| ︙ | ︙ | |||
536 537 538 539 540 541 542 |
static int try_connect(Actual_Socket sock)
{
int s;
union sockaddr_union u;
const union sockaddr_union *sa;
int err = 0;
short localport;
| | | 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 |
static int try_connect(Actual_Socket sock)
{
int s;
union sockaddr_union u;
const union sockaddr_union *sa;
int err = 0;
short localport;
int salen, family;
/*
* Remove the socket from the tree before we overwrite its
* internal socket id, because that forms part of the tree's
* sorting criterion. We'll add it back before exiting this
* function, whether we changed anything or not.
*/
|
| ︙ | ︙ | |||
691 692 693 694 695 696 697 |
break;
default:
assert(0 && "unknown address family");
exit(1); /* XXX: GCC doesn't understand assert() on some systems. */
}
| | < < | 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 |
break;
default:
assert(0 && "unknown address family");
exit(1); /* XXX: GCC doesn't understand assert() on some systems. */
}
nonblock(s);
if ((connect(s, &(sa->sa), salen)) < 0) {
if ( errno != EINPROGRESS ) {
err = errno;
goto ret;
}
} else {
|
| ︙ | ︙ | |||
1251 1252 1253 1254 1255 1256 1257 | /* * On a listening socket, the readability event means a * connection is ready to be accepted. */ union sockaddr_union su; socklen_t addrlen = sizeof(su); int t; /* socket of connection */ | < | < < | 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 |
/*
* On a listening socket, the readability event means a
* connection is ready to be accepted.
*/
union sockaddr_union su;
socklen_t addrlen = sizeof(su);
int t; /* socket of connection */
memset(&su, 0, addrlen);
t = accept(s->s, &su.sa, &addrlen);
if (t < 0) {
break;
}
nonblock(t);
if (s->localhost_only &&
!sockaddr_is_loopback(&su.sa)) {
close(t); /* someone let nonlocal through?! */
} else if (plug_accepting(s->plug, t)) {
close(t); /* denied or error */
}
|
| ︙ | ︙ |
Changes to unix/uxplink.c.
| ︙ | ︙ | |||
392 393 394 395 396 397 398 |
enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof;
int try_output(int is_stderr)
{
bufchain *chain = (is_stderr ? &stderr_data : &stdout_data);
int fd = (is_stderr ? STDERR_FILENO : STDOUT_FILENO);
void *senddata;
| | | < < | | | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof;
int try_output(int is_stderr)
{
bufchain *chain = (is_stderr ? &stderr_data : &stdout_data);
int fd = (is_stderr ? STDERR_FILENO : STDOUT_FILENO);
void *senddata;
int sendlen, ret;
if (bufchain_size(chain) > 0) {
int prev_nonblock = nonblock(fd);
do {
bufchain_prefix(chain, &senddata, &sendlen);
ret = write(fd, senddata, sendlen);
if (ret > 0)
bufchain_consume(chain, ret);
} while (ret == sendlen && bufchain_size(chain) != 0);
if (!prev_nonblock)
no_nonblock(fd);
if (ret < 0 && errno != EAGAIN) {
perror(is_stderr ? "stderr: write" : "stdout: write");
exit(1);
}
}
if (outgoingeof == EOF_PENDING && bufchain_size(&stdout_data) == 0) {
close(STDOUT_FILENO);
|
| ︙ | ︙ |
Changes to unix/uxproxy.c.
| ︙ | ︙ | |||
302 303 304 305 306 307 308 |
} else if (pid == 0) {
close(0);
close(1);
dup2(to_cmd_pipe[0], 0);
dup2(from_cmd_pipe[1], 1);
close(to_cmd_pipe[0]);
close(from_cmd_pipe[1]);
| | | | 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
} else if (pid == 0) {
close(0);
close(1);
dup2(to_cmd_pipe[0], 0);
dup2(from_cmd_pipe[1], 1);
close(to_cmd_pipe[0]);
close(from_cmd_pipe[1]);
noncloexec(0);
noncloexec(1);
execl("/bin/sh", "sh", "-c", cmd, (void *)NULL);
_exit(255);
}
sfree(cmd);
close(to_cmd_pipe[0]);
|
| ︙ | ︙ |
Changes to unix/uxpty.c.
| ︙ | ︙ | |||
369 370 371 372 373 374 375 |
cloexec(pty->master_fd);
pty->name[FILENAME_MAX-1] = '\0';
strncpy(pty->name, ptsname(pty->master_fd), FILENAME_MAX-1);
#endif
| < < < < < | < < < | 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 |
cloexec(pty->master_fd);
pty->name[FILENAME_MAX-1] = '\0';
strncpy(pty->name, ptsname(pty->master_fd), FILENAME_MAX-1);
#endif
nonblock(pty->master_fd);
if (!ptys_by_fd)
ptys_by_fd = newtree234(pty_compare_by_fd);
add234(ptys_by_fd, pty);
}
/*
|
| ︙ | ︙ |