Pregunta

Aquí está mi código:

#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;
}

Lo que realmente estoy tratando de hacer es simplemente imprimir "Stack Overflow" en el archivo usando printf () en lugar de la llamada del sistema Write ().

No está imprimiendo el contenido en el archivo. Pero una cosa que observé es que si elimino el código:

 close(newfd)

Está imprimiendo el contenido en el archivo como se esperaba. Pero no puedo entender por qué. Imprimí el contenido y luego solo estoy cerrando el Newfd.

¿Cuál es la razón de esto?

¿Fue útil?

Solución

Lo que realmente está sucediendo aquí es que printfLa salida se amortigua y no se envía a FD 1 de inmediato; en su lugar, el búfer se descarga al descriptor de archivo 1 por el tiempo de ejecución C después de regresar de main. Si usted close(newfd), Efectivamente, ha obstruido el rubor automático que de otro modo realizará el tiempo de ejecución en la salida.

Si explícitamente fflush(stdout) antes de ti close(newfd), su salida debe aparecer en el archivo.

Por cierto, si desea redirigir un descriptor de archivo específico, hay una llamada al sistema alternativa dup2(oldfd, 1) lo que hace que FD 1 sea un duplicado de oldfd, Cerrar FD 1 si estaba abierto anteriormente.

Otros consejos

Cuando usa los descriptores de archivos directamente, querrá evitar usando las funciones C stdio como printf. Cambiar el descriptor de archivo subyacente desde debajo de la capa Stdio parece tenso de peligro.

Si cambias tu printf A lo siguiente:

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

entonces probablemente obtendrá la salida que espera (si su close(newfd) O no).

close, write, open son llamadas del sistema principalmente hecho dentro del núcleo de Linux; Entonces, desde el punto de vista de la aplicación, son operaciones atómicas elementales.

printf y fprintf son funciones de biblioteca estándar construidas sobre estos (y otros) Syscalls.

Antes salida-ing (por ejemplo, regresar de main), la biblioteca y el entorno estándar (en particular el código en crt*.o Llamando a tu main) está ejecutando las funciones registradas por atexit; y la E/S estándar es (más o menos) registrar una llamada a fflush en la hora de salida. Entonces el stdout es fflush-Ed en el momento de la salida. Si usted close Su descriptor en Main, esa descarga falla y no hace nada.

Creo que no deberías mezclar stdio y crudo write-s al mismo descriptor de escritura. Considere usar fdopen o freopen

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top