2016-03-30 19 views
0

numaralı bir arabelleğe yönlendir. Daha önce sorulan sorulara baktım. Ve stderr'in şu anki değerini elde etmek için bu kodu buldum, bir dirseğe yeniden yönlendir ve stderr'i yeniden ata. Bu kod.strol öğesini c

Stderr'in buff'a yeniden yönlendirilmesi gerçekleşmiyor.

 ls: cannot access system: No such file or directory 
    hellow world 
    error from buffer 

kaynak kod şuna benzer:: Ben kodu çalıştırmak denediğimde ekranda görebilirsiniz

#include<stdio.h> 
static int fd; 
static fpos_t pos; 
char *buf; 

void closeerr() 
{ 
    fflush(stderr); 
    fgetpos(stderr, &pos); 
    fd = dup(fileno(stderr)); 
    buf =(char *)calloc(sizeof(char *),1024); 
    stderr = fmemopen(buf, sizeof(buf), "w"); 
} 

void reverterr() 
{ 
    fflush(stderr); 
    dup2(fd, fileno(stderr)); 
    close(fd); 
    clearerr(stderr); 
    fsetpos(stderr, &pos); 
} 

void main() 
{ 
    closeerr(); 
    printf("hellow world"); 
    system(" ls -l system"); // this is where I see the error msg 
    printf("error from buffer %s",buf); 
    reverterr(); 
} 

Bu kod yönlendirmeleri ile stdout (mantık aynı olurdu yeniden doğrudan bir geçici dosya (Yaklaşım 1'e) stderr ben çatallı vermemekle beraber aşağıda önerilen ve dosyaya yazmak için bir çocuk süreç)

void switchStdout(const char *newStream) 
{ 
    fflush(stdout); 
    fgetpos(stdout, &pos); 
    fd = dup(fileno(stdout)); 
    freopen(newStream, "w", stdout); 

}

oluşturdu olarak 0
void revertStdout() 
{ 
    fflush(stdout); 
    dup2(fd, fileno(stdout)); 
    close(fd); 
    clearerr(stdout); 
    fsetpos(stdout, &pos); 
} 

void main(){ 
    switchStdout("/tmp/err.txt"); 
    printf("Hello world"); 
    revertStdout(); 
} 
+0

char * buf; 'ne verildi düşünüyorsunuz? Sizeof (buf); 'nedir? –

cevap

1

fmemopen() işlevi aslında fmemopen() getiri tanımlanmamış bir değer elde bir FILE üzerine böylece fileno(), bir dosya tanıtıcı açılmaz. fmemopen(), verileri işletim sisteminden hiç göndermeden doğrudan arabelleğe yazılarak uygulanır. ile açılmış olan dosyayı fork() aracılığıyla korumak mümkün değildir.

Başka bir sorun, arabellek için belleği hiçbir zaman ayırmamanız, fmemopen() API'sini ve sorunu anlamak için nasıl kullanacağınızdır.

  • sonra fork(), geçici bir dosyayı açmak:

    Burada çalışan iki yaklaşımlardır. Çatallı işleminde, dosya tanımlayıcısını 2 dosya tanımlayıcısını 2 (STDERR_FILENO) üzerine kopyalayın ve sonra komutunuzu yürütün. Ebeveyn için çocuk için wait(), daha sonra geçici dosyaya yazdıklarını okuyun. Çocuğun dosya işaretçisini değiştireceği için okumadan önce bir lseek() yapmalısınız.

  • pipe() ile bir fifo açın, daha sonra fork(). Çocuğunuzda, yazım dosyasını dosya tanıtıcısı 2 üzerinden kopyalayın, okuma ucunu kapatın ve ardından komutunuzu yürütün. Ebeveynte, yazıyı bitirin ve çocuğun okuma sırasında okumasını yazarken okuyun. Daha sonra çocuk için wait()'u unutma.
+0

Çıktıyı bir tampon dosyasına yeniden yönlendirmek yerine geçici bir temp dosyasına yazma (temp dosyasından sonra arabelleğe) yaklaşımını düşündüm. Hafif bir aşırı yüklenme olurdu ve bunu yapmaktan kaçınmak istiyorum. Bu daha büyük bir sorunun gömlek el versiyonudur ve yapılan sistem çağrısının birçok örneği olabilir. – bhavs

+1

STDERR dosya numarasını doğru bir şekilde yeniden yönlendirdiğinizde, bunu önlemek mümkün değildir, tüm fprintf çağrıları ("stderr" 'mem belleğinize gidecektir, fakat stderr'i yeniden tanımladığınızda" yazma "(2'de aramalar) için hiçbir şey olmuyor – ikrabbe

+0

@ikrabbe Evet, ama çocukta, sadece dosya tanıtıcı korunur. 'Fmemopen()' bir dosya tanıtıcısı oluşturmaz, bu nedenle fmemopen() 'e dayanan herhangi bir yaklaşım baştan sona erdirilir ( – fuz

İlgili konular