Passing int to sysfs - c

I want to pass int to sysfs_store
What I tried
userspace
int tid = 5234; // can be negative as well
char buf[5];
sprintf(buf, "%d\n", tid);
write (fd, buf, 1);
driver sysfs_store
int v;
kstrtoint(buf,10,&v);
pr_info("%d\n",v); // printing only first digit 5. Should print 5234

Since sprintf() returns bytes copied count; use it
Also switch to snprintf() to avoid buffer overflows.
int data_len = snprintf(buf, sizeof(buf), "%d\n", tid);
write (fd, buf, data_len);
It's always better to have bigger buffers to cover all your scenarios.

Related

append to buffer while reading from socket

Hi I am trying to implement TCP socket stream. I have a buffer of size 12, and I am reading into this buffer in a loop.
I expected the read operation to add onto the buffer with each read call until the buffer is full, but instead, it starts from the beginning of the buffer, overwriting what is already in there on each iteration.
How can I append to the buffer with each read, so that the previous bytes are preserved?
void *th_read(void *arg)
{
reader_arg_t *rArg = (reader_arg_t *)arg;
int buf_size = 12;
int bytes_recevied, rv;
char buf[buf_size];
while (1)
{
rv = 0;
bytes_recevied = rv;
memset(buf, 0, buf_size);
socket_context_t ctx;
tsq_dequeue(rArg->reader_queue, &ctx);
printf("reading from socket: %i\n", ctx.sockfd);
while (1)
{
rv = read(ctx.sockfd, buf, buf_size - bytes_recevied);
if (rv < 1)
break;
bytes_recevied += rv;
printf("bytes_recevied: %i\nbuf: %s\n", bytes_recevied, buf);
}
perror("read");
close(ctx.sockfd);
printf("%s\n", buf);
}
}
When I connect with telnet and write 2 times separates by pressing enter, I get this output. Writing hello the first time and the digit 1 the second time.
reading from socket: 5
bytes_recevied: 7
buf: hello
bytes_recevied: 10
buf: 1
lo
I want the buffer to contain hello1 instead of 1\rlo.
I found a question that showed the zero byte thing but its not useful for my use case unless I would maybe use a second buffer and add on each read the stuff from the first buffer until the zero byte.
reading buffer from socket
You should send new position of buffer into read function.
rv = read(ctx.sockfd, buf + bytes_received, buf_size - bytes_recevied);

Array of buffer always changing values

I have this code for verify what's in the array buffer, but i'm always getting different values on array and it makes my program getting a 56( 8 on ascii) when its not supose too, can somebody helps ?
This sends a buffer for socket to be read on file 1:
void send_stream(char buff[], int sockfdes)
{
if (write(sockfdes, buff, strlen(buff) + 1) == -1) {
perror("ERROR: envia_stream: simulador");
}
}
void prepare_message(int tipo, int id)
{
char buff[3];
buff[1] = id;
switch (tipo)
{
case CRIACAO_P:
buff[0] = '1';
//buff[2] = tempo; //HORA
send_stream(buff, sockfd);
break;
}
this file 2 read from socket and put in buffer:
char buffer[5];
while(1)
{
read(novosockfd, buffer, sizeof(buffer));
if (buffer[0] == '8')//FIM
{
printf("Buffer[0]: %d \n", buffer[0]);
printf("Buffer[1]: %d \n", buffer[1]);
printf("Buffer[2]: %d \n", buffer[2]);
printf("Buffer[3]: %d \n", buffer[3]);
printf("Buffer[4]: %d \n", buffer[4]);
printf("\nSimulação terminou\n");
break;
}
}
}
firstly you should tell us from where are you reading from, if you are reading from a socket, trying to implement a server or are you reading from a local socket?
Also, you should also check for the return type, like this:
if ( (read(novosockfd, buffer, sizeof(buffer)) <= 0 ) {
perror("error in read");
} else
{
//code to run if the read did not failed;
}
Note that for perror to work you have to #include
perror will automatically print the message in "" followed by the error description in the console. After you do all this, come and tell us more details.
Take not that if you do not check for failure in read, your code continues to get executed.
Judging by your update, you are first writing a buffer of size 4 bytes and reading for a buffer of 5 bytes, note that reading from a socket blocks until receiving the specified size in buffer, hence if you send 4 bytes to that socket, you can't expect to be able to read 5 bytes. So in order to be able to send the message, you should have char buff[4] declared in preare_message() instead of char buff[3], and also the parameter for the size of the message in the method write(int fildes, const void *buf, size_t nbytes) is of type size_t, so you should use : write(sockfdes, buff, sizeof(char) * strlen(buffer) + 1);
And you are also assigning id(int) into a char buffer.

Write n bytes and read n bytes: sending number of bytes to read using uint16_t

I've been using these read and write functions (provided by #alk).
The problem is that I don't know how to correctly send the uint16_t data_size;.
Here is my actual code to send a general example buffer:
uint16_t data_size;
int retry_on_interrupt = 0;
char buffer[] = "Hello world!";
data_size = (uint16_t) sizeof(buffer);
/* sending data_size */
writen(socket, data_size, 2, retry_on_interrupt);
/* sending buffer */
writen(socket, buffer, sizeof(buffer);
And here is my actual code to receive a general example buffer:
/* receiving data_size */
readn(socket, &data_size, 2);
/* receiving buffer */
readn(socket, buffer, data_size);
But this is not working, I think because writen requires a const char *, instead I'm using a uint16_t...
How should these calls be? Thanks.
Replace
writen(socket, data_size, 2, retry_on_interrupt);
by
if (-1 == writen(socket, &data_size, sizeof data_size, 1))
{
perror("writen() failed writing size");
exit(EXIT_FAILURE);
}
and replace this line
writen(socket, buffer, sizeof(buffer);
by
if (-1 == writen(socket, buffer, data_size, 1))
{
perror("writen() failed writing pay-load");
exit(EXIT_FAILURE);
}
You definitely want to add error-checking to the reading functions as well!
Also you want to take care of a possible endianness (byte-order) issue, when sending/receiving between to different hardware-platforms.

How to minimize the number of system calls? in C

How to minimize the number of system calls read() and write() in my code ?
int copy(char* entry, char* exit){
char buf;
int in;
int out;
in = open(entry,O_RDONLY);
out = open(exit ,O_APPEND|O_WRONLY);
while(read(in, &buf, 1) != 0){
write(out, &buf, 1); }
close(in);
close(out);
return 0;
}
Assuming you enlarge your buffer to for example 256, now write:
char buf[256];
int n;
...
while((n=read(in, buf, sizeof(buf))) > 0){
write(out, buf, n);
}
This reads, upon every read, a maximum of 256 bytes. read returns the number of bytes read, so n now has this number, which is what you write out. The last read will be less than 256, so the last write will also be less than 256.

Using read and write to do a server and a client (FTP protocol)

My code is too long to post all here so i'm going to sum up what's wrong.
In a server part i'm sending on a socket 3 things :
A message
The content of a file
Another message
In a client part i'm receiving these things but :
This first is to print on terminal
The second to write in a new file
The last to print on the terminal too
But my client is stuck on a read and i really don't know why. I'm on the problem for hour so if someone can help me, it will be very great !
edit : Basically, i think my problem is that i don't know what to write on the server to stop the read on the client.. Is it \n, \0.. ?
Here's the 2 part of code :
server
void send_content(t_server *s, FILE *fd, int rfd)
{
int len;
char *buff;
write(s->socket, "150 File status okay;" \
"about to open data connection.\n\0", strlen("150 File status okay;about to open data connection.\n\0"));
fseek(fd, 0, SEEK_END);
len = ftell(fd);
buff = malloc(len * sizeof(char));
read(rfd, buff, len);
write(s->socket, buff, len);
write(s->socket, "\n\0", strlen("\n\0"));
write(s->socket, "226 Closing data connection.\n\0", strlen("226 Closing data connection.\n\0"));
free(buff);
}
client
void getfile(t_client *c, char **tab)
{
int ret;
int fd;
int z;
char buff[4096];
z = 0;
read(c->fd, buff, 4096);
write(1, buff, strlen(buff));
if (strlen(buff) < 25)
return ;
fd = creat(tab[1], S_IRUSR | S_IWUSR);
while (z == 0 && (ret = read(c->fd, buff, 4096)) > 0)
{
if (ret < 4096)
z = -1;
write(fd, buff, strlen(buff));
memset(buff, '\0', 4096);
}
read(c->fd, buff, 4096); // Stuck here
write(1, buff, strlen(buff));
close(fd);
}
Like noted you need a read function like this to make sure you receive
specified number of bytes(this function will loop till it receives number of bytes it was told to). Just use this receivall method instead of read everywhere.
With files you typically first send the file length, and then receive the file.
I did something similar while ago, hope it will help you a bit. This is the client side, which tries to receive first file length from the server, then the file:
/* create file */
FILE * ptrMyFile = fopen(&filenames[i][0],"wb");
if(NULL == ptrMyFile)
{
printf("Unable to open file \n");
return 1;
}
int size = 0;
int t = 4;
/* first receive file size from server */
/* NOTE: error checking is omitted from code, nevertheless users should stil do some error checking when using this code */
readall(sockfd, (unsigned char*) &size, &t);
/* how many 256 byte chunks are there? */
int div = size / 256;
/* loop to receive each chunk. */
for(int k = 0; k < div; k++)
{
int chunk_size = 256;
/* make sure we receive 256 bytes */
readall(sockfd, buffer, &chunk_size);
/* write to file */
fwrite(buffer, chunk_size, 1, ptrMyFile);
}
/* read the final chunk. */
int whatsleft = size - 256 * div;
readall(sockfd, buffer, &whatsleft);
/* write */
fwrite(buffer, whatsleft, 1, ptrMyFile);
/* close file */
fclose(ptrMyFile);
I leave the server part to you.
char buff[4096];
z = 0;
read(c->fd, buff, 4096);
write(1, buff, strlen(buff));
You should be saving the return value of the call to read(), in order to find out how many bytes you just received. You may have to make several calls to read() in order to get the entire message. It's wrong to use strlen() to find out how many bytes were received, because the buffer contents are uninitialized, and the first chunk of the message could be cut off anywhere, so you can't count on it being null-terminated.

Resources