Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 避免在Solaris操作系统上重写文件_C_Linux_Solaris - Fatal编程技术网

C 避免在Solaris操作系统上重写文件

C 避免在Solaris操作系统上重写文件,c,linux,solaris,C,Linux,Solaris,我对某些记录到文件的C库函数(顺便说一句,我无法访问其源代码)有问题。编译这些库的某些版本时,将函数附加到日志文件中。但之前的版本根本不追加 是否有某种方法(如Linux中的chattr)可以“强制”操作进入附加模式?我不允许对文件执行任何特定操作,例如在使用这些库重新启动代理之前复制它们。。。所以我唯一的选择就是强制这些函数附加到文件中,而不管它们是如何被编程打开的 谢谢。我能想到的唯一可能的解决办法是在日志文件创建后立即重命名它。由于程序有一个打开的文件描述符,它可以继续在那里写入,但下一次

我对某些记录到文件的C库函数(顺便说一句,我无法访问其源代码)有问题。编译这些库的某些版本时,将函数附加到日志文件中。但之前的版本根本不追加

是否有某种方法(如Linux中的chattr)可以“强制”操作进入附加模式?我不允许对文件执行任何特定操作,例如在使用这些库重新启动代理之前复制它们。。。所以我唯一的选择就是强制这些函数附加到文件中,而不管它们是如何被编程打开的


谢谢。

我能想到的唯一可能的解决办法是在日志文件创建后立即重命名它。由于程序有一个打开的文件描述符,它可以继续在那里写入,但下一次打开将创建一个不同的文件


例如,您可以使用一个守护进程来扫描日志文件所在的目录,并在找到一个目录后立即对其进行适当的重命名。

我能想到的唯一可能的解决方法是在创建日志文件后立即对其进行重命名。由于程序有一个打开的文件描述符,它可以继续在那里写入,但下一次打开将创建一个不同的文件


例如,您可以使用一个守护进程来扫描日志文件所在的目录,并在找到一个目录后立即对其进行适当的重命名。

一种方法是使用一个会重载
libc
fopen
open
函数的守护进程,并在请求的文件是目标文件之一。是一个插入
fopen
调用的示例,您可以轻松地适应自己的需要

或者,您可以在所谓的破坏性模式下使用
dtrace
,拦截相同的打开调用,并动态修补参数或在覆盖文件之前备份文件


是类似黑客的一个例子。

一种方法是使用一个会重载
libc
fopen
open
函数的函数,并会在请求的文件是目标文件之一时动态更改其模式参数。是一个插入
fopen
调用的示例,您可以轻松地适应自己的需要

或者,您可以在所谓的破坏性模式下使用
dtrace
,拦截相同的打开调用,并动态修补参数或在覆盖文件之前备份文件


是类似黑客攻击的一个示例。

在Solaris 11及更高版本上,您正在查找的
chattr
命令的等价物是
chmod S+vappendonly file
,但它必须以root用户身份执行,并且会导致覆盖现有数据或以错误模式打开文件的尝试出错,而不仅仅是将操作转换为静默追加,因此可能无法与某些应用程序一起工作(例如,vi不能处理这样的文件).

在Solaris 11及更高版本上,与您正在查找的
chattr
命令等效的命令是
chmod S+vappendonly file
,但它必须以root用户身份执行,并且会导致覆盖现有数据或以错误模式打开文件的尝试出错,而不仅仅是将操作转换为静默追加,因此可能不会使用某些应用程序(例如,vi不适用于这样的文件)。

由于所有答案都涉及某种类型的乱七八糟和黑客,我的答案如下:

  • 使用
    mkfifo
    将日志“文件”创建为命名管道
  • 运行进程 它从命名管道中读取,除了附加它所需要的内容之外,什么也不做 读取到真实的日志文件
  • 测试应用程序以确保其正常工作
在我脑海中,这很可能就是“过程”:

是的,我知道。给我一个奖励吧

或者,您可以尝试此C代码,该代码只执行读取操作(可以是常规文件或FIFO),将读取的任何内容转储到新文件中,并在收到SIGHUP后重新打开该文件:

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
// start with invalid descript so close() doesn't break things
int logFileFD = -1;
const char *logFileName = NULL;
void openLogFile( int sig )
{
    close( logFileFD );
    logFileFD = open( logFileName, O_WRONLY | O_CREAT | O_APPEND, 0644 );
}
void installSigHandler( void )
{
    struct sigaction sa;
    sigemptyset( &sa.sa_mask );
    // do NOT restart system calls
    sa.sa_flags = 0;
    sa.sa_handler = openLogFile;
    sigaction( SIGHUP, &sa, NULL );
}
int main( int argc, char **argv )
{
    logFileName = argv[ 2 ];
    openLogFile( SIGHUP );
    installSigHandler();
    int fifoFD = open( argv[ 1 ], O_RDONLY );
    for ( ;; )
    {
        char buffer[ 8 * 1024 ];
        ssize_t bytes = read( fifoFD, buffer, sizeof( buffer ) );
        if ( bytes > 0L ) write( logFileFD, buffer, bytes );
    }
}
#包括
#包括
#包括
#包括
#包括
#包括
//从无效的描述符开始,这样close()就不会破坏东西
int logFileFD=-1;
const char*logFileName=NULL;
void openLogFile(int-sig)
{
关闭(logFileFD);
logFileFD=open(logFileName,O|u WRONLY | O|u CREAT | O|u APPEND,0644);
}
空安装工(空)
{
struct-sigaction-sa;
sigemptyset(和sa.sa_面具);
//不要重新启动系统调用
sa.sa_标志=0;
sa.sa_handler=openLogFile;
sigaction(SIGHUP,&sa,NULL);
}
int main(int argc,字符**argv)
{
logFileName=argv[2];
openLogFile(SIGHUP);
安装sighandler();
int fifoFD=打开(argv[1],仅限Ordu);
对于(;;)
{
字符缓冲区[8*1024];
ssize_t bytes=read(fifoFD,buffer,sizeof(buffer));
如果(字节>0L)写入(logFileFD,缓冲区,字节);
}
}

我真的压缩了代码,并停止了几乎所有的错误检查,以消除任何滚动条。

因为所有的答案都涉及到一些乱七八糟的东西,下面是我的:

  • 使用
    mkfifo
    将日志“文件”创建为命名管道
  • 运行进程 它从命名管道中读取,除了附加它所需要的内容之外,什么也不做 读取到真实的日志文件
  • 测试应用程序以确保其正常工作
在我脑海中,这很可能就是“过程”:

是的,我知道。给我一个奖励吧

或者,您可以尝试此C代码,该代码只执行读取操作(可以是常规文件或FIFO),将读取的任何内容转储到新文件中,并在收到SIGHUP后重新打开该文件:

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
// start with invalid descript so close() doesn't break things
int logFileFD = -1;
const char *logFileName = NULL;
void openLogFile( int sig )
{
    close( logFileFD );
    logFileFD = open( logFileName, O_WRONLY | O_CREAT | O_APPEND, 0644 );
}
void installSigHandler( void )
{
    struct sigaction sa;
    sigemptyset( &sa.sa_mask );
    // do NOT restart system calls
    sa.sa_flags = 0;
    sa.sa_handler = openLogFile;
    sigaction( SIGHUP, &sa, NULL );
}
int main( int argc, char **argv )
{
    logFileName = argv[ 2 ];
    openLogFile( SIGHUP );
    installSigHandler();
    int fifoFD = open( argv[ 1 ], O_RDONLY );
    for ( ;; )
    {
        char buffer[ 8 * 1024 ];
        ssize_t bytes = read( fifoFD, buffer, sizeof( buffer ) );
        if ( bytes > 0L ) write( logFileFD, buffer, bytes );
    }
}
#包括
#包括
#包括
#包括
#包括
#包括
//从无效的描述符开始,这样close()就不会破坏东西
int logFileFD=-1;
const char*logFileName=NULL;
无效的