比使用System()调用更少Hacky方式?

时间:2013-10-04 08:02:05

标签: c linux maintainability

所以我有一个旧的,令人讨厌的C代码,我在这个项目中继承了一个软件工程师,后来转向更环保的牧场。好消息是...... IT运行!更好的消息是它似乎没有错误。

问题是它被设计为在服务器上运行,并在命令行上输入一组启动参数。现在,有一个新的要求,这个服务器是可重新配置的(没有看到那个即将到来......)。基本上,如果服务器通过UDP接收命令,它将启动该程序,停止它,或者通过UDP端口传入新的启动参数重新启动它。

基本上我正在考虑用于运行混淆程序的代码是这样的(对不起,我没有在我面前的实际来源,它是12:48 AM,我无法入睡,所以我希望下面的伪代码就足够了):

//my "bad_process_manager"

int manage_process_of_doom() {
  while(true) {
    if (socket_has_received_data) {
      int return_val = ParsePacket(packet_buffer);
      // if statement ordering is just for demonstration, the real one isn't as ugly...
      if (packet indicates shutdown) {
        system("killall bad_process");  // process name is totally unique so I'm good?
      } else if (packet indicates restart) {
        system("killall bad_process");  // stop old configuration
        // start with new parameters that were from UDP packet...
        system("./my_bad_process -a new_param1 -b new_param2 &");
      } else {  // just start
        system("./my_bad_process -a new_param1 -b new_param2 &");
    }
  }
}

因此,由于我必须调用system()调用,我想知道在没有所有system()调用的情况下是否有更简洁的方法。我想确保我已经用尽所有可能的选项,而不必破解C文件。我担心实际操作所有这些值会导致必须重写我继承的整个文件,因为它从未被设计为在程序运行时可配置。

另外,在开始这个过程方面,我是否正确地假设投掷“&”在system()中,调用将立即返回,就像我从命令行运行该行一样,我将控制终端返回?最后,有没有办法确保stderr(甚至可能是stdout)被打印到运行“manager”的终端屏幕上?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您需要从服务器获取什么:

理想情况下,您正在控制的服务器进程应该创建某种PID文件。理想情况下,只要服务器进程仍在运行,它就应该对PID文件保持独占锁定。这使我们可以知道PID文件是否仍然有效或服务器是否已经死亡。

接收关闭消息:

尝试锁定PID文件,如果成功,你没有什么可以杀死的(服务器已经死了,如果你继续杀死,不管怎样,你可能会杀死错误的进程),只需删除旧的PID文件

如果锁定失败,请读取PID文件并对PID执行 kill() ,删除旧的PID文件。

接收开始消息:

您需要 fork() 一个新流程,然后选择 exec() 的风格来启动新的服务器流程。服务器本身当然应该重新创建它的PID文件并对其进行锁定。

接收重启消息:

关机相同,然后是开始