📄 myinetd.cpp
字号:
// myinetd.cpp// program to start a server the same way inetd does// copyright SafeTP Development Group, Inc., 2000 Terms of use are as specified in license.txt#include "sockutil.h" // listen_socket, etc.#include "test.h" // ARGS_MAIN#include <stdlib.h> // atoi#include <stdio.h> // perror#include <sys/types.h> // waitpid (argument macros?)#include <sys/wait.h> // waitpid#define FD_STDIN 0#define FD_STDOUT 1#define FD_STDERR 2int entry(int argc, char *argv[]){ if (argc < 3) { printf("usage: %s [interface:]port prog-to-run [prog's arguments]\n", argv[0]); printf(" (note: must run as root if port < 1024)\n"); return 0; } // interpret arguments IPAddress interface; int port; parseAddrAndPort(interface, port, argv[1]); char const *progToRun = argv[2]; // listen for a connection SOCKET listener = interface_listen_socket(interface, port); // declare socket to carry info outside loop SOCKET conn; // loop until killed for (;;) { // reap up to two zombie children on each pass, just to // keep the total # of zombies reasonable (around 1-2) loopi(2) { int status; // dummy, don't care waitpid(-1 /*any child*/, &status, WNOHANG /*nonblocking*/); // ignore return; may not be any children to reap, I don't care } // wait for incoming, and make a new socket for it when it arrives fprintf(stderr, "%s: listening for incoming connection at %s...\n", argv[0], formatAddress(interface, port).pcharc()); conn = accept_socket(listener); fprintf(stderr, "%s: received connection %s, starting %s\n", argv[0], sockInfo(conn).pcharc(), progToRun); // fork a child to finish up and run the real server int forkRet = fork(); if (forkRet == -1) { perror("fork"); } else if (forkRet != 0) { // this is the parent, will go back to the top of the loop } else { // this is the child // we don't need to have a handle to the listener; the parent // still has it and should continue using it close(listener); // break out of the loop and exec the server break; } // if we're here because of an error, we close because we can't start // the server, and don't want whoever connected just hanging around; // if we're here on the normal path, the child now has a duplicate // of this socket, and so we can close it close(conn); } // this is the child's normal path #if 1 // replace *my* stdin, stdout, stderr with the new connection if (dup2(conn, FD_STDIN) < 0 || dup2(conn, FD_STDOUT) < 0 || //dup2(conn, FD_STDERR) < 0 || false) { perror("dup2"); return 2; } #else // since my current version of sftpd doesn't have the full logging // facilities I want, and I know it only uses fd 0 (stdin) as the // client connection, I'll just put the conn on FD_STDIN, and let // the debugging output just go to the same place as this program's if (dup2(conn, FD_STDIN) < 0) { perror("dup2"); return 2; } #endif // having duplicated it now, the original file descriptor is redundant close(conn); // exec the other program, with the remaining arguments to this program execv(argv[2], argv+2); // if execv returns, an error occurred perror("execv"); return 4;}ARGS_MAIN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -