Domanda

Ecco il mio codice:

#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
int main(int argc,char *argv[])
{
  int oldfd;
  int newfd;
  if(argc!=2)
  {
    printf("Usgae : %s file_name\n",argv[0]);
    exit(0);
  }
 oldfd=open(argv[1],O_RDWR|O_APPEND,S_IRWXU); // Opening the file in Read/Write mode
 if (-1 == oldfd)
 {
  perror("Error opening file");
  exit(0);
 }
 close(1); // closing stdout 
 newfd=dup(oldfd); //Now this newfd holds the value 1 
 close(oldfd); //closing the oldfd
 printf("\nStack Overflow"); //Now this printf will print content into the file as stdout closed already
 close(newfd);// closing newfd 
 return 0;
}

Quello che sto effettivamente cercando di fare è semplicemente stampare "stack overflow" al file usando printf () invece di scrivere () chiamata di sistema.

Non sta stampando il contenuto nel file. Ma una cosa che ho osservato è che se rimuovo il codice:

 close(newfd)

Sta stampando il contenuto nel file come previsto. Ma non riesco a capire perché. Ho stampato il contenuto e poi solo sto chiudendo il Newfd.

Qual è il motivo per questo?

È stato utile?

Soluzione

Quello che sta realmente accadendo qui è quello printfL'output è bufferita e non inviata immediatamente a FD 1; Invece il buffer viene scaricato nel descrittore di file 1 dal tempo di esecuzione C dopo il ritorno da main. Se tu close(newfd), hai effettivamente ostruito il flusso automatico che viene altrimenti eseguito dal tempo di esecuzione all'uscita.

Se esplicitamente fflush(stdout) prima di te close(newfd), il tuo output dovrebbe apparire nel file.

A proposito, se si desidera reindirizzare un descrittore di file specifico, esiste una chiamata di sistema alternativa dup2(oldfd, 1) che rende FD 1 un duplicato di oldfd, chiudendo FD 1 se era precedentemente aperto.

Altri suggerimenti

Quando usi direttamente i descrittori di file, lo vorrai evitare usando le funzioni C stdio come printf. Cambiare il descrittore di file sottostante da sotto lo strato STDIO sembra irto di pericolo.

Se cambi il tuo printf a quanto segue:

write(newfd, "\nStack Overflow", 15);

allora probabilmente otterrai l'output che ti aspetti (se il tuo close(newfd) o no).

close, write, open sono chiamate di sistema Per lo più fatto all'interno del Kernel Linux; Quindi dal punto di vista dell'applicazione, sono operazioni atomiche elementari.

printf e fprintf sono funzioni di libreria standard costruite sopra questi (e altri) Syscalls.

Prima Uscita-ing (ad esempio il ritorno da main), la libreria e l'ambiente standard (in particolare il codice in crt*.o chiamando il tuo main) sta eseguendo le funzioni registrate da atexit; e l'I/O standard è (una specie di) che registra una chiamata a fflush Al momento di uscita. Così la stdout è fflush-Ed al tempo di uscita. Se tu close Il suo descrittore in main, che il flush non fallisce e non fa nulla.

Penso che non dovresti mescolare stdio e crudo write-S allo stesso descrittore di scrittura. Prendi in considerazione l'uso fdopen o freopen

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top