Returning multiple file pointers in C - c

I'm new to C and would like some help with an issue I have. I'm reading and writing to pipes as follows:
f = fdopen(fdH2P[WRITE], "w"); // writing to pipe, returns a file pointer
and
r = fdopen(fdP2H[READ], "r"); // reading from pipe
I want to return both these file pointers from my function. What's the best way to do that?

You can either put the two file pointers into a structure and return that, or you can pass pointers to the function, like this
void GetPipes( FILE **wptr, FILE **rptr )
{
*wptr = fdopen(fdH2P[WRITE], "w");
*rptr = fdopen(fdP2H[READ], "r");
}
void SomeOtherFunction( void )
{
FILE *wptr, *rptr;
GetPipes( &wptr, &rptr );
...
}

You can return a struct:
Define struct, with typedef for convenience
typedef struct dual_fp {
FILE *read_fp;
FILE *write_fp;
} dual_fp;
Add function to open two files
dual_fp dual_fdopen(int write_fd, int read_fd) {
dual_fp ret;
// review error handling and reporting,
// such as add error code fields to struct dual_fp,
// and possibly do not open 2nd / close 1st file if the other fails
ret.write_fp = fdopen(write_fd, "w");
if (!ret.write_fp) perror("dual_fdopen for write");
ret.read_fp = fdopen(read_fd, "r");
if (!ret.read_fp) perror("dual_fdopen for read");
return ret;
}
Call it
dual_fp fps = dual_fdopen(fdH2P[WRITE], fdopen(fdP2H[READ]);
// use fps.read_fp and fps.write_fp after checking they are not NULL

Create a struct and return an instance of the struct.
typedef struct
{
FILE* write;
FILE* read;
} FilePointers;
FilePointers foo()
{
// Assuming you have access to the data...
FILE* w = fdopen(fdH2P[WRITE], "w");
FILE* r = fdopen(fdP2H[READ], "r");
FilePointers fp = {w, r};
return fp;
}

Related

File access control in linux

I`m writing a module to control file access. I'm now trying to implement the prohibition of file opening. I've already tried are kernel module system open overload: http://pastebin.com/JWKbpFYT
I've also tried system read overload: http://pastebin.com/psK8vX41
The problem in the first one is that I could restrict access to target file only in console (it didn't work in graphical interface, e.g. gedit).
The second one didn't work as the system stopped responding on running gedit with target file.
How can I prohibit file opening without using SELinux?
asmlinkage int custom_open(const char __user *file_name, int flags, mode_t mod)
{
printk("hook: open(\"%s\")", file_name);
if (!strcmp(file_name, "test"))
return -1;
return original_open(file_name, flags, mod);
}
struct file *fget(unsigned int fd)
{
struct file *file;
struct files_struct *files = current->files;
rcu_read_lock();
file = fcheck_files(files, fd);
if (file) {
/* File object ref couldn't be taken */
if (file->f_mode & FMODE_PATH ||
!atomic_long_inc_not_zero(&file->f_count))
file = NULL;
}
rcu_read_unlock();
return file;
}
asmlinkage int custom_read(int fd, void *buf, size_t noct)
{
struct file *filp = fget(fd);
unsigned char f_name[DNAME_INLINE_LEN];
strcpy(f_name,filp->f_path.dentry->d_name.name);
if (!strcmp(f_name, "_ttt.c")){
printk("hook1: read fd=(%d: -> %s)\n",fd,f_name);
return -1;
}
return original_read(fd, buf, noct);
}

Problem writing struct to file

I have a problem with a function which should write a struct to a file, the files are created however they stay empty whatever I do.
This is the struct that I'm trying to write to the file:
typedef struct
{
double dA;
double dA1;
double dB;
double dB1;
double dAwnser;
char cStepOne[24];
char cStepTwo[24];
char cStepThree[20];
char cFormula[26];
} equationData_t;
equationData_t equation;
This is the function to write the struct to a file:
void writeDataToFile(equation)
{
int iSizeOfStruct = 0;
char cFileName[20];
int iQuitProgram = 0;
iSizeOfStruct = sizeof(equationData_t);
while (1)
{
printf("Give file name with extension (Max 20 char.):\n:");
scanf("%s",&cFileName[0]);
pnf = fopen(cFileName, "r+");
if (pnf == NULL)
{
printf ("\nError: File not found!\n1.Try again.\n2.Quit.\n3.Make new file.\n:");
scanf("%d",&iQuitProgram);
switch(iQuitProgram)
{
case 1: break;
case 2: exit(1);
case 3: makeNewFile();
}
}
if (pnf != NULL)
{
printf("\n************************************\nFile opend!\nWriting data to file.\n");
fwrite(equation, iSizeOfStruct, 1, pnf);
fclose(pnf);
printf("Data written");
break;
}
}
}
You can try to use open() and then pwrite() instead of fopen() and the fwrite().
However, in your code:
fwrite(equation, iSizeOfStruct, 1, pnf);
should be modified in:
fwrite(&equation, iSizeOfStruct, 1, pnf);

C - using global structure

I'm using global structure so I can set/get error or state from everywhere. It was working fine, now I'm in trouble.
structure
typedef struct program Program;
struct program
{
int error;
int state;
};
// global declarations
Program *program;
init
void init_memory(void)
{
program = malloc(sizeof(Program));
if(program == NULL)
{
print_error(E_MEM_ALLOC);
exit(EXIT_FAILURE);
}
program->state = S_NONE;
program->error = E_OK;
}
here program crashes, when I remove "program->error = ...." program is working fine...i don't know why :/
void check_file(char *filename)
{
FILE *file = fopen(filename, "r");
if(file == NULL)
{
program->error = E_FILE_OPEN;
return;
}
fclose(file);
}
whole program: http://pastebin.com/dwSVQ9x8
Making program a pointer seems unnecessary, why not just make it the actual struct:
Program program = { .error = E_OK, .state = S_NONE };
Then you don't need to worry about allocating it (and can indeed remove init_memory altogether). Just change access to its members to use . instead of ->, i.e., program.error = E_FILE_OPEN.

saving simple XML files

I started using XML format to create file, for this purpose I use this code :
void xml_create_file()
{
mxml_node_t *xml;
mxml_node_t *data;
FILE *f;
xml = mxmlNewXML("1.0");
data = mxmlNewElement(xml, "setting");
data = mxmlNewElement(xml, "URL");
data = mxmlNewText(data, 0, "http://192.168.55.55");
f = fopen("/etc/share/backup.xml", "wb");
if (f==NULL) {
close(f);
printf("backup could not be written.\n");
}
else {
mxmlSaveFile(xml, f, MXML_NO_CALLBACK);
close(f);
mxmlDelete(data);
mxmlDelete(xml);
printf("backup Saved\n");
}
}
when I check the file /etc/share/backup.xml, I found it empty !!!
how to resolve this problem ?
note : I use microxml lib
close(f)
should be
fclose(f)
(The compiler should have warned you about this.)

C Programming - File - fwrite

I've got a question regarding programming and files.
while(current!=NULL)
{
if(current->Id_Doctor!='\0')
{
current=current->next;
id_doc=(current->Id_Doctor);
}
if(current->Id_Doctor=='\0')
{
id_doc=id_doc+1;
printf("%d", id_doc);
break;
}
}
fwrite(&id_doc, sizeof(char), 1, Archivo);
I dont know why but it aint writing the value of id_doc on the binary file called 'Archivo'...what could be the problem?
I added a printf of id_doc and the value was printed..I really dont know
Ok, heres the full code(more-less):
struct Medico
{
int Id_Doctor;
int Estado;
char Nombre[60];
char Clave_Acceso[20];
char Especialidad[40];
struct Medico *next;
};
void Dar_Alta_Med (int estado);
void MenuPrincipal(char enta);
int main(void)
{
char enta;
MenuPrincipal(enta);
}
void Dar_Alta_Med(int estado)
{
struct Medico * head = NULL;
struct Medico * prev, *current;
char nombre_doc[60], especialida[40], password[20];
int id_doc=0, estado_doc=1;
FILE *Archivo;
const char *md1="\n<md>\n";
const char *id_doc1="<id_doctor> ";
Archivo=fopen("md.dat", "ab+");
fwrite(md1, 1, strlen(md1), Archivo);
fwrite(id_doc1, 1, strlen(id_doc1), Archivo);
current = (struct Medico *) malloc (sizeof(struct Medico));
current->Id_Doctor=id_doc;
while(current!=NULL)
{
if(current->Id_Doctor!='\0')
{
current=current->next;
id_doc=(current->Id_Doctor);
}
else
{
id_doc=id_doc+1;
printf("%d", id_doc);
break;
}
}
fwrite(&id_doc, sizeof(id_doc), 1, Archivo);
printf("Ingresa el nombre del Doctor a dar de alta: ");
fclose(Archivo);
}
Im dying here, please help :/
Try adding fflush(Archivo); to force a write of all buffered data.
Also, this statement: if(current->Id_Doctor=='\0') really ought to be an else since there is no other thing it can be but '\0'
Three things:
Make sure your fopen is successful.
Archivo=fopen("md.dat", "ab+");
if (Archivo == NULL)
{
perror("Failed to open file Archivo");
...
}
Make sure you are checking the success of your fwrite's.
if (fwrite(&id_doc, sizeof(id_doc), 1, Archivo) < 1)
{
perror("Failed to write to file Archivo");
...
}
Make sure you have a fclose to close the file properly.
if (fclose(Archivo) != 0)
{
perror("Failed to close file Archivo");
...
}
Now that you've post a full sample of your code I guess I should ask if error checking is just left out for brevity? If not, you should think about adding it.
If you're expecting the value of id_doc to be in display format in the output file you'll have to convert the int to a string (using snprintf or similar) and write the string to the output file instead.
fwrite(&id_doc, sizeof(char), 1, Archivo);
If you defined id_doc as anything other than a char it will write \0 to the file.
Much cleaner would be:
fwrite(&id_doc, sizeof(id_doc), 1, Archivo);
If your first current is an Id_Doctor you have an endless loop.
If there is no current after your last current that is not an Id_Doctor, you get an illegal pointer derefenciation.
For your Problem:
try the flush() family.
You're passing a pointer to a FOUR-BYTE INT, but only writing ONE BYTE (the wrong byte)!
Solution: declare id_doc as "char", not "int".
You have previously written the strings "\n<md>\n" and"<id_doctor> " to the file Archivo, which seems to indicate that it is not a binary file at all, but rather an XML-style file.
In this case, what you almost certainly want is:
fprintf(Archivo, "%d", id_doc);

Resources