changing size of a block device in c linux - c

I have written a function that should change the size of any block device
lsblk command gives this output
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 465.8G 0 disk
├─sda1 8:1 0 457.9G 0 part /
├─sda2 8:2 0 1K 0 part
└─sda5 8:5 0 7.9G 0 part [SWAP]
my function is->
int _some_func(
int path,
int size)
{
struct stat stat_buf;
/*check if file is valid*/
if(!((fcntl(path, F_GETFL) != -1) || (errno != EBADF)))
{
perror("invalid file descriptor\n");
return -1;
}
/*get file properties in stat_buf*/
if( -1 == fstat(path, &stat_buf))
{
perror("error in stat\n");
return -1;
}
/*return error -1 if file is not block device*/
if((stat_buf.st_mode & S_IFMT) != S_IFBLK)
{
perror("not a block device\n");
return -1;
}
return(ftruncate(path,size) );
}
int main()
{
long int curr_size = 0;
struct stat stat_buf;
int fd = open("/dev/sda1",O_RDWR,0777);
if(fd < 0) perror("error\n");
/*get file properties in stat_buf*/
if( -1 == fstat(fd, &stat_buf))
{
perror("error in stat\n");
return -1;
}
curr_size = stat_buf.st_size;
printf("current size =%ld\n",curr_size);
if(_ss_size(fd,curr_size+50) == 0)
{
/*get file properties in stat_buf*/
if( -1 == fstat(fd, &stat_buf))
{
perror("error in stat\n");
return -1;
}
curr_size = stat_buf.st_size;
printf("changed size =%ld\n",curr_size);
}
else
{
perror("error in _ss_size\n");
}
}
output is->
current size =0
error in _ss_size
: Invalid argument
1>why the current size of "/dev/sda1" is showing as 0,but in lsblk size is = 457.9G
2>why error in _ss_size
: Invalid argument is coming(this is the return value of)
ftruncate command.
if ftruncate does not work, then which sys call will work?

Related

Can the Pagemap folder of processes in the Linux kernel be read(64bit per read) a finite number of times?

I'm trying to keep track of the number of writes per physical page in the file "proc/PID/pagemap".But the file is binary, and the size shown in the file properties is 0, and the following function reads 0 as well.
struct stat buf;
int iRet = fstat(fd, &buf);
if(iRet == -1)
{
perror("fstat error");
exit(-1);
}
printf("the size of file is : %ld\n", buf.st_size);
I write a monitor program to read data from a process's "pagemap" 64bit one time and record the 55-bit(soft dirty bit)to check if one page is written.Of course before doing this I cleared all soft dirty bit in a process's pagemap.This method is provided by linux kernel and my question during coding is that when I use file descriptor(also tried fstream pointer) to get the data from pagemap.My reading of pagemap ends only when the process I'm monitoring is finished, as if the file were infinite.I know the process's logical address mangement is dynamic but I want to know how could I count the write number properly.Should I read a part of this infinite file within a fixed time intervals?And how many items should I read? T _ T.
You need something like the following:
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
struct pagemap_region {
struct pagemap_region *next;
uintptr_t addr; /* First address within region */
uintptr_t ends; /* First address after region */
size_t pages; /* Number of pages in this region */
uint64_t page[]; /* 64-bit pagemap flags per page */
};
static void free_pagemaps(struct pagemap_region *list)
{
while (list) {
struct pagemap_region *curr = list;
list = curr->next;
curr->addr = 0;
curr->ends = 0;
curr->pages = 0;
free(curr);
}
}
struct pagemap_region *get_pagemaps(const pid_t pid)
{
struct pagemap_region *list = NULL;
size_t page;
char *line_ptr = NULL;
size_t line_max = 256;
ssize_t line_len;
FILE *maps;
int n, fd;
page = sysconf(_SC_PAGESIZE);
/* We reuse this for the input line buffer. */
line_ptr = malloc(line_max);
if (!line_ptr) {
errno = ENOMEM;
return NULL;
}
/* First, fill it with the path to the map pseudo-file. */
if (pid > 0)
n = snprintf(line_ptr, line_max, "/proc/%d/maps", (int)pid);
else
n = snprintf(line_ptr, line_max, "/proc/self/maps");
if (n < 0 || (size_t)n + 1 >= line_max) {
free(line_ptr);
errno = EINVAL;
return NULL;
}
/* Read the maps pseudo-file. */
maps = fopen(line_ptr, "re"); /* Read-only, close-on-exec */
if (!maps) {
free(line_ptr);
errno = ESRCH;
return NULL;
}
while (1) {
struct pagemap_region *curr;
unsigned long addr, ends;
size_t pages;
char *ptr, *end;
line_len = getline(&line_ptr, &line_max, maps);
if (line_len < 0)
break;
/* Start address of the region. */
end = ptr = line_ptr;
errno = 0;
addr = strtoul(ptr, &end, 16);
if (errno || end == ptr || *end != '-')
break;
/* End address of the region. */
ptr = ++end;
errno = 0;
ends = strtoul(ptr, &end, 16);
if (errno || end == ptr || *end != ' ')
break;
/* Number of pages in the region. */
pages = (ends - addr) / page;
if (addr + page * pages != ends || (addr % page) != 0)
break;
/* Allocate new region map. */
curr = malloc(sizeof (struct pagemap_region) + pages * sizeof curr->page[0]);
if (!curr)
break;
curr->addr = addr;
curr->ends = ends;
curr->pages = pages;
/* Prepend to the region list. */
curr->next = list;
list = curr;
}
/* Any issues when reading the maps pseudo-file? */
if (!feof(maps) || ferror(maps)) {
fclose(maps);
free(line_ptr);
free_pagemaps(list);
errno = EIO;
return NULL;
} else
if (fclose(maps)) {
free(line_ptr);
free_pagemaps(list);
errno = EIO;
return NULL;
}
/* Reuse the line buffer for the pagemap pseudo-file path */
if (pid > 0)
n = snprintf(line_ptr, line_max, "/proc/%d/pagemap", (int)pid);
else
n = snprintf(line_ptr, line_max, "/proc/self/pagemap");
if (n < 0 || (size_t)n + 1 >= line_max) {
free(line_ptr);
free_pagemaps(list);
errno = ENOMEM;
return NULL;
}
do {
fd = open(line_ptr, O_RDONLY | O_NOCTTY | O_CLOEXEC);
} while (fd == -1 && errno == EINTR);
if (fd == -1) {
n = errno;
free(line_ptr);
free_pagemaps(list);
errno = n;
return NULL;
}
/* Path no longer needed. */
free(line_ptr);
line_ptr = NULL;
line_max = 0;
/* Read each pagemap section. */
for (struct pagemap_region *curr = list; curr != NULL; curr = curr->next) {
off_t offset = (size_t)(curr->addr / page) * (sizeof curr->page[0]);
unsigned char *ptr = (unsigned char *)&(curr->page[0]);
size_t need = curr->pages * sizeof curr->page[0];
ssize_t bytes;
while (need > 0) {
bytes = pread(fd, ptr, need, offset);
if (bytes >= need)
break;
else
if (bytes > 0) {
ptr += bytes;
offset += bytes;
need -= bytes;
} else
if (bytes == 0) {
/* Assume this is a region we can't access, like [VSYSCALL]; clear the rest of the bits. */
memset(ptr, 0, need);
break;
} else
if (bytes != -1 || errno != EINTR) {
close(fd);
free_pagemaps(list);
errno = EIO;
return NULL;
}
}
}
if (close(fd) == -1) {
free_pagemaps(list);
errno = EIO;
return NULL;
}
return list;
}
int main(int argc, char *argv[])
{
struct pagemap_region *list, *curr;
long pid;
char *end;
if (argc != 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
const char *argv0 = (argc > 0 && argv && argv[1]) ? argv[1] : "(this)";
fprintf(stderr, "\n");
fprintf(stderr, "Usage: %s [ -h | --help ]\n", argv0);
fprintf(stderr, " %s PID\n", argv0);
fprintf(stderr, "\n");
fprintf(stderr, "This program prints the a map of the pages of process PID;\n");
fprintf(stderr, "R for pages in RAM, S for pages in swap space, and . for others.\n");
fprintf(stderr, "You can use -1 for the PID of this process itself.\n");
fprintf(stderr, "\n");
return EXIT_SUCCESS;
}
end = argv[1];
errno = 0;
pid = strtol(argv[1], &end, 10);
if (errno || end == argv[1] || *end) {
fprintf(stderr, "%s: Invalid PID.\n", argv[1]);
return EXIT_FAILURE;
}
if (pid != -1 && (pid < 1 || (long)(pid_t)pid != pid)) {
fprintf(stderr, "%s: Not a valid PID.\n", argv[1]);
return EXIT_FAILURE;
}
list = get_pagemaps(pid);
if (!list) {
fprintf(stderr, "%s.\n", strerror(errno));
return EXIT_FAILURE;
}
for (curr = list; curr != NULL; curr = curr->next) {
printf("Region %p - %p: %zu pages\n", (void *)(curr->addr), (void *)(curr->ends), curr->pages);
for (uint64_t *map = curr->page; map < curr->page + curr->pages; map++) {
if ((*map >> 63) & 1)
putchar('R');
else
if ((*map >> 62) & 1)
putchar('S');
else
putchar('.');
}
putchar('\n');
}
return EXIT_SUCCESS;
}
We read /proc/PID/maps line by line, and construct a struct pagemap_region for each; this contains the start address, the end address, and the number of pages in the region. (I didn't bother to support huge pages, though; if you do, consider parsing /proc/PID/smaps instead. If a line begins with a 0-9 or lowercase a-f, it specifies an region; otherwise the line begins with a capital letter A-Z and specifies a property of that region.)
Each struct pagemap_region also contains room for the 64-bit pagemap value per page. After the regions have been found/chosen – this one tries all –, the /proc/PID/pagemap file is opened, and the corresponding data read from the proper location using pread(), which works like read(), but also takes the file offset as an extra parameter.
Not all regions are accessible. I do believe [VSYSCALL] is one of those, but being a kernel-userspace interface, its pagemap bits are uninteresting anyway. Instead of removing such regions from the list, the above just clears the bits to zero.
This is not intended as a "do it exactly like this, just copy and paste this" answer, but as a suggestion of how to start going about this, perhaps exploring a bit, comparing the results or behaviour to your particular needs; a sort of a rough outline for an initial suggestion only.
Also, as I wrote it in a single sitting, it's likely got nasty bugs in it. (If I knew where or for sure, I'd fix them; it's just that bugs happen.)

Destination and Source file don't match - C

I've been trying to find out why my tester is failing, it says that destination and source file don't match. link for testers: https://github.com/ShiraWolf/hwOP.git
Output Requirements & Testing:
It must output one of the following types of messages (precisely and case-sensitive):
Unable to open source file for reading
Unable to open destination file for writing
Unable to write to destination file
Unable to write buffer content to destination file
Unable to read source file
Unable to close source file
Unable to close destination file
File was successfully copied to
Or one of the various arguments parsing errors, as described in the examples above.
My code:
/*
* ex1.c
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MAX_BUFFER_SIZE 65536
#define DESTINATION_FILE_MODE S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH
extern int opterr, optind;
void exit_with_usage(const char *message) {
fprintf(stderr, "%s\n", message);
fprintf(stderr, "Usage:\n\tex1 [-f] BUFFER_SIZE SOURCE DEST\n");
exit(EXIT_FAILURE);
}
void copy_file(const char *source_file, const char *dest_file, int buffer_size, int force_flag) {
/*
* Copy source_file content to dest_file, buffer_size bytes at a time.
* If force_flag is true, then also overwrite dest_file. Otherwise print error, and exit.
*
* TODO:
* 1. Open source_file for reading
* 2. Open dest_file for writing (Hint: is force_flag true?)
* 3. Loop reading from source and writing to the destination buffer_size bytes each time
* 4. Close source_file and dest_file
*
* ALWAYS check the return values of syscalls for errors!
* If an error was found, use perror(3) to print it with a message, and then exit(EXIT_FAILURE)
*/
int c = 0;
int sourcef = 0;
int destf = 0;
sourcef = open(source_file, O_RDONLY);
if (sourcef == -1) {
perror("Unable to open source file for reading");
exit(EXIT_FAILURE);
}
destf = open(dest_file, O_WRONLY |O_CREAT | O_EXCL, 00700);
if (destf == -1) {
if (force_flag) {
destf = open(dest_file, O_WRONLY, 00700);
if (destf == -1) {
if (close(sourcef) == -1) {
perror("couldn't close source file");
exit(EXIT_FAILURE);
}
perror("Unable to open destination for writing");
exit(EXIT_FAILURE);
}
} else {
perror("Unable to open destination for writing");
exit(EXIT_FAILURE);
}
}
char *buffer = malloc(sizeof(char) * buffer_size);
while ((c = read(sourcef, buffer, buffer_size)) != 0) {
if (c == -1) {
perror("couldn't read from source file");
if (close(sourcef) == -1) {
perror("couldn't close source file after reading has failed");
exit(EXIT_FAILURE);
}
if (close(destf) == -1) {
perror("couldn't close dest file after reading has failed");
exit(EXIT_FAILURE);
}
exit(EXIT_FAILURE);
}
c = write(destf, buffer, buffer_size);
if (c == -1) {
perror("couldn't write to source file");
if (close(sourcef) == -1) {
perror("couldn't close source file after writing has failed");
exit(EXIT_FAILURE);
}
if (close(destf) == -1) {
perror("couldn't close dest file after writing has failed");
exit(EXIT_FAILURE);
}
exit(EXIT_FAILURE);
}
}
free(buffer);
if (close(sourcef) == -1) {
perror("couldn't close source file");
exit(EXIT_FAILURE);
}
if (close(destf) == -1) {
perror("couldn't close dest file");
exit(EXIT_FAILURE);
}
printf("File %s was copied to %s\n", source_file, dest_file);
exit(EXIT_SUCCESS);
}
void parse_arguments (
int argc, char **argv,
char **source_file, char **dest_file, int *buffer_size, int *force_flag) {
/*
* parses command line arguments and set the arguments required for copy_file
*/
int option_character;
opterr = 0; /* Prevent getopt() from printing an error message to stderr */
while ((option_character = getopt(argc, argv, "f")) != -1) {
switch (option_character) {
case 'f':
*force_flag = 1;
break;
default: /* '?' */
exit_with_usage("Unknown option specified");
}
}
if (argc - optind != 3) {
exit_with_usage("Invalid number of arguments");
} else {
*source_file = argv[argc - 2];
*dest_file = argv[argc - 1];
*buffer_size = atoi(argv[argc - 3]);
if (strlen(*source_file) == 0 || strlen(*dest_file) == 0) {
exit_with_usage("Invalid source / destination file name");
} else if (*buffer_size < 1 || *buffer_size > MAX_BUFFER_SIZE) {
exit_with_usage("Invalid buffer size");
}
}
}
int main(int argc, char **argv) {
int force_flag = 0; /* force flag default: false */
char *source_file = NULL;
char *dest_file = NULL;
int buffer_size = MAX_BUFFER_SIZE;
parse_arguments(argc, argv, &source_file, &dest_file, &buffer_size, &force_flag);
copy_file(source_file, dest_file, buffer_size, force_flag);
return EXIT_SUCCESS;
}
Can anybody see where my mistake is?
c = write(destf, buffer, buffer_size); does not use the correct size: you should write c bytes and store the written count into a separate variable nwritten and keep trying to write more bytes until c bytes have been written or write return 0 or -1.
Here is a modified version of the copying loop:
while ((c = read(sourcef, buffer, buffer_size)) != 0) {
if (c == -1) {
perror("Unable to read from source file");
if (close(sourcef) == -1) {
perror("Unable to close source file");
exit(EXIT_FAILURE);
}
if (close(destf) == -1) {
perror("Unable to close destination file");
exit(EXIT_FAILURE);
}
exit(EXIT_FAILURE);
}
int towrite = c;
int pos = 0;
while (towrite > 0) {
int nwritten = write(destf, buffer + pos, towrite);
if (nwritten <= 0) {
perror("Unable to write to destination file");
if (close(sourcef) == -1) {
perror("Unable to close source file");
exit(EXIT_FAILURE);
}
if (close(destf) == -1) {
perror("Unable to close destination file");
exit(EXIT_FAILURE);
}
exit(EXIT_FAILURE);
}
pos += nwritten;
towrite -= nwritten;
}
}
Also note that the other error messages are different from the specification.

Raspberry Pi RS232 read RFID Transponder

I want to open my door with a RFID Transponder. For this I use a Raspberry Pi and an 125Khz RFID Reader with UART. So now I have written a little C programm, wich sets up the RS232 ('ttyAMA0'). This works all fine, and I can read the Transponder, but it reads some sh**
Here is my Code:
char read_rfid(char* rfid_num)
{
fd_set input_fdset;
ssize_t length;
while(1)
{
FD_ZERO(&input_fdset);
FD_SET(fd,&input_fdset);
if(select(fd+1 ,&input_fdset, NULL,NULL,NULL)==-1)
perror("Terminal select() failed");
if(FD_ISSET(fd,&input_fdset))
{
if((length = read(fd,rfid_num,14)) ==-1)
perror("Terminal: read() failed");
else
{
write(STDOUT_FILENO,rfid_num,length);
return;
}
}
}
}
int setupRS232()
{
struct termios term_attr;
if((fd = open(RFID,O_RDWR)) == -1)
{
perror("Can't open Device");
return(1);
}
if(tcgetattr(fd,&term_attr) != 0)
{
perror("terminal: tcgetattr() failed");
return(1);
}
term_attr.c_cflag = BAUD|CS8|CRTSCTS|CLOCAL|CREAD;
term_attr.c_iflag = 0;
term_attr.c_oflag = 0;
term_attr.c_lflag = 0;
if(tcsetattr(fd,TCSAFLUSH,&term_attr) != 0)
{
perror("terminal: tcsetattr() failed");
return(1);
}
}
int main(int argc, char** argv)
{
MYSQL *mysql = NULL;
char rfid_num[14];
int i;
if(init_mysql(mysql) == 1)
return(1);
if(setupRS232() == 1)
return(1);
puts("Warte auf Transponder...");
read_rfid(rfid_num);
for(i=0;i<20;i++)
{
printf("%x\n",rfid_num[i]);
}
}
PS: Sorry for my bad English
Minimal approach to buffering. You should probably check the contents of the buffer before returning valid (is there a final \n ? )
char read_rfid(char* rfid_num) {
fd_set input_fdset;
ssize_t length;
int done;
for(done=0; done < 14; ) {
FD_ZERO(&input_fdset);
FD_SET(fd,&input_fdset);
if(select(fd+1 ,&input_fdset, NULL,NULL,NULL) == -1) {
if (errno == EAGAIN) continue;
perror("Terminal select() failed");
return -1;
}
if(FD_ISSET(fd,&input_fdset)) {
if((length = read(fd,rfid_num+done,14-done)) == -1) {
if (errno == EAGAIN) continue;
perror("Terminal: read() failed");
return -1;
}
write(STDOUT_FILENO,rfid_num+done,length);
done += length;
}
}
return 0;
}
Note: I don't understand why this function returns char.

Compilation error in C on Linux

I'm writing a simple program in Linux and when compiling I keep getting this error and don't understand why — I put all ; or {} in place:
ex1.c:49.1: error:expected declaration or statement at end of input
My code:
#include<sys/stat.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<fcntl.h>
int main (int argc, char* argv[])
{
if (argc!=3)
printf("Number of arugements passed is wrong - not 2\n");
char * file1 = argv[1];
char * file2 = argv[2];
int fdout1 = open(file1, O_RDONLY);
int fdout2 = open(file2, O_RDONLY);
struct stat stat_p1,stat_p2;
char * f1;
char * f2;
int i=0;
if (fdout1 < 0 || fdout2<0) /* means file open did not take place */
{
perror("ERROR opening files"); /* text explaining why */
return 1;
}
if ( (stat (file1, &stat_p1) == -1) ||( stat (file2, &stat_p2) == -1) ) /* declare the 'stat' structure */
{
printf(" Error occurred attempting to stat files");
return 1;
{
if((read(fdout1,f1,stat_p1.st_size)==-1) ||(read(fdout1,f1,stat_p1.st_size)==-1))
{
printf("ERROR reading files"); /* text explaining why */
return 1;
}
if (stat_p1.st_size!=stat_p2.st_size)
return 1;
if (strcmp(f1,f2)!=0)
return 1;
return 0;
}
Can anyone tell me why I keep getting this error?
It seems there is a typo
if ( (stat (file1, &stat_p1) == -1) ||( stat (file2, &stat_p2) == -1) ) /* declare the 'stat' structure */
{
printf(" Error occurred attempting to stat files");
return 1;
{
The last brace shall be a closing brace.
if ( (stat (file1, &stat_p1) == -1) ||( stat (file2, &stat_p2) == -1) ) /* declare the 'stat' structure */
{
printf(" Error occurred attempting to stat files");
return 1;
}
Take into account that if argc is less than 3 you have to exit the program
if (argc!=3)
printf("Number of arugements passed is wrong - not 2\n");
Otherwise these statements are invalid
char * file1 = argv[1];
char * file2 = argv[2];
if ( (stat (file1, &stat_p1) == -1) ||( stat (file2, &stat_p2) == -1) ) /* declare the 'stat' structure */
{
printf(" Error occurred attempting to stat files");
return 1;
>>>> { >>>>> change this to '}'
This error occurs when you have missing closing braces. As can be seen here:
if ( (stat (file1, &stat_p1) == -1) ||( stat (file2, &stat_p2) == -1) ) /* declare the 'stat' structure */
{
printf(" Error occurred attempting to stat files");
return 1;
{
You seem to have a typo, you should have closing brace instead of opening brace.
It should be like this
if ( (stat (file1, &stat_p1) == -1) ||( stat (file2, &stat_p2) == -1) ) /* declare the 'stat' structure */
{
printf(" Error occurred attempting to stat files");
return 1;
}
The closing brace is the problem, here it was opening brace on your program.

File partially sent in c

I'm trying to send files using TCP from a windows client to a Linux server in C.
The size of the buffer I use to send the data is 65535. When the size of the file exceeds this value, I get an error saying 'connection reset by peer' or the error code 10054. When the size of the file is less than 65535 bytes, the server receives only a part of it (usually 2760 bytes).
I just want to send files with a maximum size of 50 MB.
This is the part of the windows client that I use to send data:
char *fileName; // pointer to filename
char buf[65535]; // buffer
int fileSize; // # bytes to send
for(i = 0; i < ARRAYSIZE; i++) {
if(selectList[i] != NULL) {
// select file
fileName= selectList[i]; // get path and filename from selectList
printf("=============================================\nSending: %s\n", fileName);
filefd = fopen(fileName, "rb"); // open file
if(filefd == NULL) {
printf("File %s not found\n", fileName);
exit(1);
}
// read and send file
memset(buf, '\0', 65535);
while((fileSize= fread(buf, sizeof(char), 65535, filefd)) > 0) { // read file
if((numberOfBytes = send(sockfd, buf, fileSize, 0)) < 0) { // send buffer
printf("send: %s (Error: %d)\n", filename, WSAGetLastError());
break;
}
printf("#bytes = %i \n", numberOfBytes);
memset(buf, '\0', 65535);
}
printf("File %s send!\n", filename);
// close file after sending it
if(fclose(filefd) < 0) {
printf("fclose: %i", WSAGetLastError());
}
} else if(selectList[0] == NULL) {
printf("no files selected");
}
}
The selectList contains multiple strings such as: C:\Windows\test.txt
The recieve part of the Linux server:
char* fr_name = "/home/MtFS/UploadedFiles/public/testFile.gif";
FILE *fr = fopen(fr_name, "wb");
if(fr == NULL)
printf("[Open_File]file %s cannot be created\n", fr_name);
else {
bzero(revbuf, LENGTH);
int fr_block_sz = 0;
while((fr_block_sz = recv(nsockfd, revbuf, LENGTH, 0)) > 0) {
int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
if(write_sz < fr_block_sz) {
error("[Write] error\n");
}
bzero(revbuf, LENGTH);
if (fr_block_sz == 0 || fr_block_sz != 512) {
break;
}
}
if(fr_block_sz < 0) {
if (errno == EAGAIN) {
printf("[Receive] time out\n");
}
else {
printf("[Receive] error\n");
exit(1);
}
}
printf("[Receive] succesfull\n");
fclose(fr);
}
What am I doing wrong?
Your problem are those 3 lines of code. That's not the correct way to know that you're done:
if (fr_block_sz == 0 || fr_block_sz != 512) {
break;
}
Also you check against 512 instead of LENGTH. But only 0 means that you're done (assuming your connection is not NONBLOCKED.)
As a side note: you do not have to clear your buffers (bzero, memset) before using them with a read since the read/recv will overwrite the content of the buffers anyway.
I think the culprit is this line in your server
if (fr_block_sz == 0 || fr_block_sz != 512) {
fr_block_sz cab be anything between 1 to 65535 - the size block that you sent.
In your code, when its not 512 so your server is terminating the connection.

Resources