I'm trying to read a file using file descriptors (which is probably a lot more work than I need to do, but nonetheless..)
I'm trying to create an archiver similar to ar. I have a non empty file I'm trying to read from but when I try the read command to retrieve the first 8 bytes the return int is 0 which means it didn't read any bytes. And errno tells me everything went fine.
What I'm trying to do is read the string at the beginning of the file so I may run string comparisons.
Sorry about the spaghetti code, I'm still testing and trying to figure things out.
The problem is at the statement temp = read(archiveFD,buf,8); archiveFD points to my archive file, which is non empty but nothing is read.
command:
./a.out r ar.c archive.a
ar.c:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <utime.h>
#include <errno.h>
#define BUF_SIZE 1024
int main(int argc, char *argv[]) {
int fileFD, archiveFD, openFlags;
mode_t filePerms;
ssize_t numRead;
char buf[BUF_SIZE];
char fileName[16];
const struct utimbuf *times;
char modTime[12];
char entry[29];
int temp;
char *line = NULL;
size_t len = 0;
if(strcmp(argv[1], "r") != 0 && strcmp(argv[1], "x") != 0 && strcmp(argv[1], "d") != 0 && strcmp(argv[1], "t") != 0) {
printf("%s","Not a valid command.\n");
return 0;
}
if(strcmp(argv[1], "r") == 0) {
if(argv[3] == NULL) {
printf("%s","Missing arguments.\n");
return 0;
}
fileFD = open(argv[2], O_RDONLY);
if(fileFD == -1) {
printf("%s","Error opening input file.\n");
return 0;
}
openFlags = O_CREAT | O_RDWR | O_TRUNC;
filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
archiveFD = open(argv[3], openFlags, filePerms);
if(archiveFD == -1) {
printf("%s","Error opening archive file.\n");
return 0;
}
temp = read(archiveFD,buf,8);
//printf("%s",(char *) buf);
// if(strcmp("!<arch>\n",buf) != 0)
// write(archiveFD,"!<arch>\n",8); //begins archive
// printf("%s","here");
//}
printf("%d",temp);
printf("%s",strerror(errno));
//printf("%s",buf);
sprintf(fileName,"%-16s",argv[2]);
printf("%s",fileName);
utime(argv[2],times);
//strcpy(modTime,"12345678901234");
//printf("%s",modTime);
sprintf(modTime,"%-.12lld",(long long) times->modtime);
modTime[12] = '\0';
printf("%s",modTime);
sprintf(entry,"%s%s\n",fileName,modTime);
printf("%s",entry);
write(archiveFD,entry,29);
while((numRead = read(fileFD, buf, BUF_SIZE)) > 0)
if(write(archiveFD, buf, numRead) != numRead) {
printf("%s","Could not write whole buffer.\n");
return 0;
}
if(numRead == -1) {
printf("%s","Error reading.\n");
return 0;
}
if(close(fileFD) == -1) {
printf("%s","Error closing input file.\n");
return 0;
}
if(close(archiveFD) == -1) {
printf("%s","Error closing archive file.\n");
return 0;
}
}
return 0;
}`
archive.a:
ar.c 140737161196
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <utime.h>
#include <errno.h>
#define BUF_SIZE 1024
int main(int argc, char *argv[]) {
int fileFD, archiveFD, openFlags;
mode_t filePerms;
ssize_t numRead;
char buf[BUF_SIZE];
char fileName[16];
const struct utimbuf *times;
char modTime[12];
char entry[29];
int temp;
char *line = NULL;
size_t len = 0;
if(strcmp(argv[1], "r") != 0 && strcmp(argv[1], "x") != 0 && strcmp(argv[1], "d") != 0 && strcmp(argv[1], "t") != 0) {
printf("%s","Not a valid command.\n");
return 0;
}
if(strcmp(argv[1], "r") == 0) {
if(argv[3] == NULL) {
printf("%s","Missing arguments.\n");
return 0;
}
fileFD = open(argv[2], O_RDONLY);
if(fileFD == -1) {
printf("%s","Error opening input file.\n");
return 0;
}
openFlags = O_CREAT | O_RDWR | O_TRUNC;
filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
archiveFD = open(argv[3], openFlags, filePerms);
if(archiveFD == -1) {
printf("%s","Error opening archive file.\n");
return 0;
}
temp = read(archiveFD,buf,8);
//printf("%s",(char *) buf);
// if(strcmp("!<arch>\n",buf) != 0)
// write(archiveFD,"!<arch>\n",8); //begins archive
// printf("%s","here");
//}
printf("%d",temp);
printf("%s",strerror(errno));
//printf("%s",buf);
sprintf(fileName,"%-16s",argv[2]);
printf("%s",fileName);
utime(argv[2],times);
//strcpy(modTime,"12345678901234");
//printf("%s",modTime);
sprintf(modTime,"%-.12lld",(long long) times->modtime);
modTime[12] = '\0';
printf("%s",modTime);
sprintf(entry,"%s%s\n",fileName,modTime);
printf("%s",entry);
write(archiveFD,entry,29);
while((numRead = read(fileFD, buf, BUF_SIZE)) > 0)
if(write(archiveFD, buf, numRead) != numRead) {
printf("%s","Could not write whole buffer.\n");
return 0;
}
if(numRead == -1) {
printf("%s","Error reading.\n");
return 0;
}
if(close(fileFD) == -1) {
printf("%s","Error closing input file.\n");
return 0;
}
if(close(archiveFD) == -1) {
printf("%s","Error closing archive file.\n");
return 0;
}
}
return 0;
}
In this block: (error checking omitted for brevity)
openFlags = O_CREAT | O_RDWR | O_TRUNC;
filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
archiveFD = open(argv[3], openFlags, filePerms);
temp = read(archiveFD,buf,8);
I would absolutely expect read to return zero. You just opened the file with O_TRUNC,
so even if the file wasn't empty, it is after you open it. If you do not want to discard all existing data, remove O_TRUNC from openFlags.
Related
I'm trying to create a function that duplicates a file given a file descriptor and a file name:
int filedup(int fd1, char *cpyfile)
{
int fd;
size_t rd;
char buff;
if (fd1 < 0 || fd1 > OPEN_MAX)
return (-1);
if (!validfname(fname))
return (-1);
fd = open(cpyfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1)
return (-1);
rd = read(fd1, &buff, 1);
while (rd > 0)
{
write(fd, &buff, 1);
rd = read(fd1, &buff, 1);
}
close(fd);
return (0);
}
int main(void)
{
int fd;
fd = open("/tmp/cpyfromfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd == -1)
return (-1);
putstr_fd(strdup("hello world\n"), fd);
filedup(fd, "cpyfile");
close(fd);
return (0);
}
I tried to debug it, and the problem was rd == 0 even though the file contains data.
$ cat ./cpyfile
$ (nothing)
I'm not sure what's the problem ? what am i doing wrong ?
So the task is to adapt the strategy to develop two applications so when the client sends messages with shared memory, the server application can log the message to log file. You should append the new message to the log file with a new line at end of the file, so the log file will grow as more messages are logged into it. the starting code is in the logger.zip file. You need to use additional variables, file pointers, and logarithms needed to make the program work.
code:
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
int main(void) {
size_t bytesWritten = 0;
int my_offset = 0;
char *text1Ý="Data for file 1.";
char *text2Ý="Data for file 2.";
int fd1,fd2;
int PageSize;
void *address;
void *address2;
fd1 = open("/reading.txt",
(O_CREAT | O_TRUNC | O_RDWR),
(S_IRWXU | S_IRWXG | S_IRWXO) );
if ( fd1 < 0 )
perror("open() error");
else {
bytesWritten = write(fd1, text1Ý, strlen(text1Ý));
if ( bytesWritten != strlen(text1Ý) ) {
perror("write() error");
int closeRC = close(fd1);
return -1;
}
fd2 = open("/writing.txt",
(O_CREAT | O_TRUNC | O_RDWR),
(S_IRWXU | S_IRWXG | S_IRWXO) );
if (fd2 < 0 )
perror("open() error");
else {
bytesWritten = write(fd2, text2Ý, strlen(text2Ý));
if ( bytesWritten != strlen(text2Ý) )
perror("write() error");
PageSize = (int)sysconf(_SC_PAGESIZE);
if ( PageSize < 0) {
perror("sysconf() error");
}
else {
off_t lastoffset = lseek( fd1, PageSize-1, SEEK_SET);
if (lastoffset < 0 ) {
perror("lseek() error");
}
else {
bytesWritten = write(fd1, " ", 1);
lastoffset = lseek( fd2, PageSize-1, SEEK_SET);
bytesWritten = write(fd2, " ", 1);
int len;
my_offset = 0;
len = PageSize;
address = mmap(NULL,
len,
PROT_READ,
MAP_SHARED,
fd1,
my_offset );
if ( address != MAP_FAILED ) {
address2 = mmap( ((char*)address)+PageSize,
len,
PROT_READ,
MAP_SHARED | MAP_FIXED, fd2,
my_offset );
if ( address2 != MAP_FAILED ) {
printf("\n%s",address);
printf("\n%s",address2);
}
else {
perror("mmap() error=");
}
}
else {
perror("munmap() error=");
}
if ( munmap(address, 2*PageSize) < 0) {
perror("munmap() error");
}
else;
}
}
close(fd2);
unlink( "/tmp/mmaptest2");
}
close(fd1);
unlink( "/tmp/mmaptest1");
}
}
address and address2 don't have a null terminator so you need to specify the length when printing.
e.g. printf("%.*s", length, string);
I was working on a C programming database tutorial (linked here- https://www.youtube.com/watch?v=SEenaPQXxFs )
When I go to run my code and insert new data into the database it does generate a data file, but no data is stored in the data file/database at all- im not really sure why its not working, and as far as I can tell no errors populate.
The code I was working on is as follows
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
//give structure to record
typedef struct
{
unsigned int key; //primary key assingment
char fname[16]; // defines length allowed for names
char lname[16]; //same but for last name
unsigned int age;
} person_rec; //gives name to definition
int open_record(char *filename) //function to open record
{
int fd;
fd = open(filename, O_CREAT | O_APPEND, 0644);
if(fd == -1)
perror("open_record");
return fd;
}
void close_record(int fd) //close record
{
close(fd);
}
int insert_record(int fd, person_rec *rec) //unkkown
{
int ret;
ret = write(fd, rec, sizeof(person_rec));
return ret;
}
//function to delete and print
int get_record(int fd, person_rec *rec, int key)
{
int ret;
while( ( ret = read(fd, rec, sizeof(person_rec)) ) != -1)
{
if(ret == 0)
{
memset(rec, 0, sizeof(person_rec)); //clear any errors by resetting size
break;
return ret;
}
else if (key == rec->key)
return ret;
}
memset(rec, 0, sizeof(person_rec)); //clear record if error due to -1 size
return ret;
}
//delete function
int delete_record(int fd, int key)
{
int ret;
person_rec rec;
off_t pos;
pos = lseek(fd, 0, SEEK_SET);
while( ( ret = read(fd, &rec, sizeof(person_rec)) ) != -1)
{
if(ret == 0)
{
return ret;
}
else if (key == rec.key)
{
lseek(fd, pos, SEEK_SET);
rec.key = 0;
ret = write(fd, &rec, sizeof(person_rec));
return ret;
}
pos = lseek(fd, 0, SEEK_CUR);
}
return ret;
}
int main(int argc, char *argv[]) //main function/uses all prior defined function to make database ect
{
int fd;
person_rec rec;
fd = open_record("data1");
if(argc > 1)
{
/* insert */
if(argc > 5 && !strcmp(argv[1], "insert"))
{
rec.key = atoi(argv[2]);
strcpy(rec.fname, argv[3]);
strcpy(rec.lname, argv[4]);
rec.age = atoi(argv[5]);
insert_record(fd, &rec);
}
/* delete */
if(argc > 2 && !strcmp(argv[1], "delete"))
delete_record(fd, atoi(argv[2]));
/*print */
if(argc > 2 && !strcmp(argv[1], "print"))
{
get_record(fd, &rec, atoi(argv[2]));
printf("key = %d\n", rec.key);
printf("First = %s\n", rec.fname);
printf("Last = %s\n", rec.lname);
printf("Age = %d\n", rec.age);
}
}
return 0;
}
From the open man page:
The argument flags must include one of the following access modes: O_RDONLY, O_WRONLY, or O_RDWR.
So:
fd = open(filename, O_CREAT | O_APPEND, 0644);
should be:
fd = open(filename, O_CREAT | O_APPEND | O_RDWR, 0644);
I don't see any call to fclose() or fflush() to empty buffer to disk. Add fflush() after every write or fclose() before exiting the program.
My script is about open a device when startup.
Actually, I think is not about code error but its about when I put my_app
on /etc/rc3.d/my_app I don't run it in background process that make it stuck on while loop and cant use Ctrl+c / Ctrl+z to cancel it because it run on startup terminal.
Any Idea to interrupt my app to exit the infinity loop ?
- what I think is try to access the data storage directly and disable/remove my symlink my_app on etc/rc3.d but I cant do that.
my OS is yocto
my app starts at runlevel 3
Here is my code.
#include <stdio.h>
#include <fcntl.h> /* File Control Definitions */
#include <termios.h> /* POSIX Terminal Control Definitions*/
#include <unistd.h> /* UNIX Standard Definitions */
#include <errno.h> /* ERROR Number Definitions */
#include <termios.h>
#include <time.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define BAUDRATE B19200 // 19200 use for input r ,, 115200
unsigned char ClearScreen[] = {254,88};
void usbreset(){
FILE *fp;
char *command;
//char *command2;
//char boss[100];
char path[1035];
//commnad = "sudo su";
command = (char *) malloc(30);
//command2 = (char *) malloc(30);
command ="lsusb | grep 1b3d:012c";
char command2[100] = "./rest ";
fp = popen(command,"r");
while (fgets(path, sizeof(path)-1, fp) != NULL) {
// printf("\n %s", path);
}
printf("%zu", strlen(path));
char final[strlen(path)-1];
printf("%s\n", path);
printf("%zu \n", strlen(path));
int x=0;
while(x < strlen(path)-1){
printf("%x ",path[x]);
final[x] = path[x];
x++;
}
printf("%s\n",final);
printf("%zu\n",strlen(final) );
// final is out put of lsusb -t
char str[40] = " ";
strcpy(str,final);
const char s[2] = " "; // token split
char *token;
//char a[22];
char bus[3] = " ";
char dev[3] = " ";
/* get the first token */
token = strtok(str, s);
//printf("%c\n", token[0]);
/* walk through other tokens */
int count = 0;
while( token != NULL ) {
if(count == 1){
strcpy(bus,token);
} else if(count == 3){
strncpy(dev,token,3);
}
token = strtok(NULL, s);
count += 1;
}
char reset_command[100] = "/dev/bus/usb/";
strcat(reset_command,bus);
strcat(reset_command,"/");
strcat(reset_command,dev);
strcat(command2,reset_command);
printf("%s\n", command2 );
fp = popen(command2,"r");
fclose(fp);
}
int main(){
//FILE *openfile;
//openfile = fopen("logfile.txt","r+b");
int fd;
FILE *fp;
char *command;
char path[16];
command ="ls /dev/ttyUSB*";
fp = popen(command,"r");
while (fgets(path, sizeof(path)-1, fp) != NULL) {
// printf("\n %s", path);
}
char final[strlen(path)-1];
int x=0;
while(x < strlen(path)-1){
//printf("%x ",path[x]);
final[x] = path[x];
x++;
}
fclose(fp);
struct termios term;
fd = open(final, O_RDWR | O_NOCTTY | O_NONBLOCK);
if(fd == 1){
printf("Error! in Opening ttyUSB0\n");
}else{
printf("Device Detected!\n");
printf("Opening Successfully\n");
}
term.c_cflag = BAUDRATE | CS8 | CSTOPB | CLOCAL | CREAD;
term.c_iflag = 0;
term.c_oflag = 0;
term.c_lflag = 0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&term);
write(fd,ClearScreen,sizeof(ClearScreen));
//int lcd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);
//fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NONBLOCK);
int err_cnt = 0;
printf("start\n");
//return 0;
while(1){
char buffer[100];
ssize_t length = read(fd, &buffer, sizeof(buffer));
if(length == -1){
//printf("Error reading from serial port\n");
//printf("%zu\n",length);
printf("%s\n",buffer );
err_cnt += 1;
printf("%d\n",err_cnt );
usbreset();
}else{
err_cnt = 0;
printf("%c", buffer[length]);
}
buffer[length] = '\0';
}
return 0;
}
So I was following a little outdated book (2010) and I'm trying to copy a file with Linux system calls. This is what i have:
NOTE: Ignore the tlpi_hdr.h and error_functions.h, they define errExit() and fatal() and some otheres, they just print the error and exit.
#include <stdio.h>
#include <fcntl.h>
#include "lib/tlpi_hdr.h"
#include "lib/error_functions.h"
#ifndef BUF_SIZE
#define BUF_SIZE 1024
#endif
int main(int argc, char *argv[])
{
int inputFd, outputFd, openFlags;
mode_t filePerms;
ssize_t numRead;
char buf[BUF_SIZE];
if (argc != 3 || strcmp(argv[1], "--help") == 0) {
usageErr("%s old-file new-file\n", argv[0]);
}
inputFd = open(argv[1], O_RDONLY);
if (inputFd == -1) {
errExit("Opening file %s", argv[1]);
}
openFlags = O_CREAT | O_WRONLY | O_TRUNC;
filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
outputFd = open(argv[2], openFlags, filePerms);
if (outputFd == -1) {
errExit("Opening file for writing %s", argv[1]);
}
while ((numRead = read(inputFd, buf, BUF_SIZE)) > 0) {
if (write(outputFd, buf, numRead) != numRead))
fatal("I/O Error");
if (numRead == -1)
fatal("Reading error");
}
if (close(outputFd == -1))
errExit("close input");
if (close(inputFd == -1))
errExit("close output");
return EXIT_SUCCESS;
}
I'm failing on closing of the output file descriptor with EBADF Bad file descriptor:
thinkpad :: ~/.tlpi % ./cp.o a b
ERROR [EBADF Bad file descriptor] close output
The file copies fine tho:
thinkpad :: ~/.tlpi % sha1sum a
40a925a93e149ac53d2630cde8adeb63b8134b29 a
thinkpad :: ~/.tlpi % sha1sum b
40a925a93e149ac53d2630cde8adeb63b8134b29 b
thinkpad :: ~/.tlpi %
Why?
Let's take a closer look at your close call:
close(outputFd == -1)
Here you are comparing outputFd to the value -1. The result of that is a boolean value, which in C will be either 0 or 1. This happens to be either standard input or standard output, depending on the result. Not a file you descriptor you should close.
My guess is that you meant
if (close(outputFd) == -1)