c multiple file descriptors - c

I am trying to make a C program that concatenates the contents of two files at a target file. To do this I must have at least 2 files open at the same time but I haven't figured out why I can't. The problem can be sufficiently described by the two pieces of code below:
Why does this work:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
int main(int argc, char* argv[]){
size_t fdes = open(argv[1], O_RDONLY);
void * buf;
int bytes;
while ((bytes = (int)read(fdes, buf, 3)) > 0) {
printf("%s", (char*)buf);
}
close(fdes);
return 0;
}
and this doesn't?
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
int main(int argc, char* argv[]){
size_t fdes = open(argv[1], O_RDONLY);
size_t fdes2 = open(argv[2], O_RDONLY);
void * buf;
int bytes;
while ((bytes = (int)read(fdes, buf, 3)) > 0) {
printf("%s", (char*)buf);
}
close(fdes);
close(fdes2);
return 0;
}
can't i have multiple files open?

I make some changes, and this works:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
int main(int argc, char* argv[]){
size_t fdes = open(argv[1], O_RDONLY);
size_t fdes2 = open(argv[2], O_RDONLY);
size_t length = 0;
char * buf = (char *)malloc(sizeof(char) * length);
int bytes;
while ((bytes = (int)read(fdes, buf, sizeof(buf) - 1)) > 0) {
printf("%s", buf);
}
while ((bytes = (int)read(fdes2, buf, sizeof(buf) - 1)) > 0) {
printf("%s", buf);
}
close(fdes);
close(fdes2);
return 0;
}
First, buf should be char *
Second, you need to point buf to somewhere (malloc or a char array)
Reference: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.bpxbd00/rtrea.htm

Related

How to keep program unclosed after ctr+c in named pipe?

I have 2 programs.
One is server one is client. The Client sending string to the server, the server is swapping the string and return to the client.
the problems I have is when I pressing ctr+c the program(client) closed.(I'm using threads because I have been asking for.)
So how can I keep the program unclosed after ctr+c?
when clicking enter this is the right result and waiting for the server.
when entering ctl+c the program closed and cannot running server.c
The client.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#define MAX_BUF 1024
// client
int main()
{
int fd;
char *myfifo = "myfifo";
char str[MAX_BUF];
printf("Input string: ");
fgets(str, MAX_BUF, stdin);
str[strlen(str) - 1] = '\0';
if (mkfifo("myfifo", 0777) == -1)
{
if (errno != EEXIST)
{
printf("Could not create fifo file\n");
return 1;
}
}
/* create the FIFO (named pipe) */
fd = open(myfifo, O_WRONLY);
if (fd == -1)
return 2;
if (write(fd, str, MAX_BUF) == -1)
return 3;
close(fd);
fd = open(myfifo, O_RDONLY);
read(fd, str, MAX_BUF);
printf("%s\n", str);
/* remove the FIFO */
unlink(myfifo);
return 0;
}
The server
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#include <pthread.h>
#define MAX_BUF 1024
// server
// creatring struct for saving data
typedef struct thread_data
{
char str[MAX_BUF];
int result;
} thread_data;
// the
void *routine(void *arg)
{
int fd[2];
char *myfifo = "myfifo";
thread_data *tdata = (thread_data *)arg;
if (!(strcmp(tdata->str, "exit")))
tdata->result = 1; // is exit
else
tdata->result = 0; // not exit
if (tdata->result == 1)
{
fd[1] = open(myfifo, O_WRONLY);
write(fd[1], "Done", sizeof(MAX_BUF));
close(fd[1]);
}
else
{
char string[MAX_BUF] = {0};
char c = 0;
int length = 0, i = 0;
length = strlen(tdata->str);
printf("\nBefore Swap : %s\n", tdata->str);
for (i = 0; i < length / 2; i++)
{
c = tdata->str[i];
tdata->str[i] = tdata->str[length - 1 - i];
tdata->str[length - 1 - i] = c;
}
printf("\nAfter Swap String : %s\n", tdata->str);
fd[1] = open(myfifo, O_WRONLY);
write(fd[1], tdata->str, sizeof(MAX_BUF));
close(fd[1]);
}
pthread_exit(NULL);
}
int Calculation()
{
int fd[2];
// fd[0] read
// fd[1] write
char *myfifo = "myfifo";
char buf[MAX_BUF];
/* open, read, and display the message from the FIFO */
fd[0] = open(myfifo, O_RDONLY);
if(fd[0]==-1)
return 4;
if(read(fd[0], buf, MAX_BUF)==-1)
return 5;
close(fd[0]);
// res
int result;
thread_data tdata;
strcpy(tdata.str, buf);
pthread_t t1;
if (pthread_create(&t1, NULL, &routine, (void *)&tdata) != 0)
{
return 1;
}
if (pthread_join(t1, NULL) != 0)
{
return 2;
}
}
int main()
{
int res = Calculation();
return res;
}
To avoid closing a program you should capture and
manage the signal sent by CTRL + C, that is SIGINT, I have modified the code so that it captures the signal CTRL + C
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#define MAX_BUF 1024
// client
int main()
{
signal(SIGINT,SIG_IGN); // Register signal handler for ignoring the signal
int fd;
char *myfifo = "myfifo";
char str[MAX_BUF];
printf("Input string: ");
fgets(str, MAX_BUF, stdin);
str[strlen(str) - 1] = '\0';
if (mkfifo("myfifo", 0777) == -1)
{
if (errno != EEXIST)
{
printf("Could not create fifo file\n");
return 1;
}
}
/* create the FIFO (named pipe) */
fd = open(myfifo, O_WRONLY);
if (fd == -1)
return 2;
if (write(fd, str, MAX_BUF) == -1)
return 3;
close(fd);
fd = open(myfifo, O_RDONLY);
read(fd, str, MAX_BUF);
printf("%s\n", str);
/* remove the FIFO */
unlink(myfifo);
return 0;
}

Why is nothing printing from the text file?

I was trying out some exercises with the C language, specifically open() and read(). However, I've reached an impasse when I try printing to STDOUT the contents of a a text file (text.txt) that I have in the same directory as the c file. The size in bytes get printed, but the contents of the file do not.
I allocated space according to the size of the file, and added "1" for the null terminator. The manual page for read() states that it reads the contents of the file into the second parameter (void* buff). What am I missing/doing wrong?
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char* argv[]){
int fd = open("text.txt", O_RDONLY);
if (fd == -1){
printf("%s\n", strerror(errno));
return -1;
}
else {
int func = lseek(fd, 0, SEEK_END);
printf("%d bytes in size\n", func);
char* ptr = (char*)malloc(sizeof(char)*func + 1);
read(fd, ptr, func);
printf("%s", ptr);
free(ptr);
}
close(fd);
return 0;
}```
You need to move back to the beginning of the file before the read.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char* argv[]){
int fd = open("text.txt", O_RDONLY);
if (fd == -1){
printf("%s\n", strerror(errno));
return -1;
}
else {
int size = lseek(fd, 0, SEEK_END);
printf("%d bytes in size\n", size);
char* ptr = (char *) malloc(sizeof(char) * size + 1);
lseek(fd, 0, SEEK_SET); // move back to the beginning
read(fd, ptr, size);
printf("%.*s", size, ptr);
free(ptr);
}
close(fd);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char* argv[]){
int fd = open("text.txt", O_RDONLY);
if (fd == -1){
printf("%s\n", strerror(errno));
return -1;
}
else {
int size = lseek(fd, 0, SEEK_END);
printf("%d bytes in size\n", size);
char* ptr = (char *) malloc(sizeof(char) * size + 1);
lseek(fd, 0, SEEK_SET); // move back to the beginning
read(fd, ptr, size);
printf("%.*s", size, ptr);
free(ptr);
}
close(fd);
return 0;
}
(venv) [ttucker#zim stackoverflow]$ cat text.txt
asdf
qwer
sdfg
(venv) [ttucker#zim stackoverflow]$ gcc -o print print.c
(venv) [ttucker#zim stackoverflow]$ ./print
15 bytes in size
asdf
qwer
sdfg

Reading a file character by character using system calls in c

I have no idea how to use system calls but after some search on internet I came up with this code. Can you please correct my code ?
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
int main()
{
char ch;
int file;
open(file, "input.txt", O_RDONLY);
read(file, ch, 1);
while (ch != '\0')
{
printf("%c", ch);
fseek(file, 1, SEEK_CUR);
read(file, ch, 1);
}
return 0;
}
you are almost right in doing, dont need to use fseek inside ,it will be automatically moved.
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int retVal = 0;
unsigned char ch;
int fdr = open(argv[1],O_RDONLY);
if( fdr )
{
while(read(fdr,&ch,1) == 1)
printf("%c", ch);
retVal = 0;
}
else
{
printf("File open failed\n");
retVal = -1;
}
return retVal;
}

Read last 20 bytes from a file

int fd, read_byte;
char *c;
fd = open("foo.txt", O_RDONLY);
read_byte = read(fd, c, 20);
printf("");
How to read last 20 bytes from a file and print the read_byte to the screen.
Use lseek(2)
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main()
{
int fd, read_byte;
char c[21];
fd = open("foo.txt", O_RDONLY);
if (fd == -1) {
printf("Error opening file\n");
return -1;
}
// reposition fd to position `-20` from the end of file.
lseek(fd, -20L, SEEK_END);
read_byte = read(fd, c, 20); // Read 20 bytes
c[read_byte] = '\0';
printf("%s\n", c);
close(fd);
return 0;
}

How to write a number (int, double) to file using file descriptor in C?

I tried this:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int out_fd = open("file.txt", O_WRONLY | O_CREAT, 0666);
int i;
scanf("%d", &i);
char tmp[12]={0x0};
sprintf(tmp,"%11d", i);
write(out_fd, tmp, sizeof(tmp));
close(out_fd);
return 0;
}
but it writes some trash to my file:
is there any good way to write a number (float, int, double) to file using file descriptor and write? Thanks
thanks guys, solved:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int out_fd = open("plik.txt", O_WRONLY | O_CREAT, 0666);
int i;
scanf("%d", &i);
char tmp[1]={0x0};
sprintf(tmp,"%d", i);
write(out_fd, tmp, strlen(tmp));
close(out_fd);
return 0;
}
You need to replace sizeof() with strlen() to get the actual length of the string to write. e.g:
write(out_fd, tmp,strlen(tmp));

Resources