C /sys/class/pwm init within a program - c

So you can see in this link that you have a pwm /sys/class/pwm/.
So I am currently putting the right data into the appropriate files and things are working well.
That is not the issue. The issue is that you need to do a "cat" on the /sys/class/pwm/{port}/request file before it becomes active. So if you reboot it will not work and you have to re-initiate it.
I have tried to just fopen("~request","r") hoping it would work but it doesn't. Opening it for "w" either. I also tried doing an exec() but that didn't work and is clunky anyhow. I don't want to have to make the assumptions required.
Here is my execv() code anyhow.
char *request[1];
request[0] = pwmbus;
execv("/bin/cat",request);
What is the most elegant way to cat the file? I din't need the information it outputs. It just initializes the sysfs. Otherwise I will be stuck having to manually do this or scripting it all the time.
cat /sys/class/pwm/gpio_pwm.0:0/request
sysfs 719

You can read one byte from the file:
int fd = open("/sys/class/pwm", O_RDONLY);
char buf[1];
read(fd, buf, 1);
close(fd);

Related

Proper methods to Copy files/folders programmatically in C using POSIX functions

These terms may not be 100% accurate, but I'm using the GCC compiler and POSIX library. I have C code compiled with the SQLite amalgamation file to a single executable.
In the user interface that exchanges JSON messages with the C program, I'd like to make it possible for users to copy the SQLite database files they create through the C program, and copy a full directory/folder.
Thus far, I've been able to rename and move files and folders programmatically.
I've read many questions and answers here, at Microsoft's C runtime library, and other places but I must be missing the fundamental points. I'm using regular old C, not C++ or C#.
My question is are there POSIX functions similar to rename(), _mkdir(), rmdir(), remove(), _stat(), that allow for programmatic copying of files and folders in Windows and Linux?
If not, can one just make a new folder and/or file and fread/fwrite the bytes from the original file to the new file?
I am primarily concerned with copying SQLite database files, although I wouldn't mind knowing the answer in general also.
Is this answer an adequate method?
Is the system() function a poor method? It seems to work quite well. However, it took awhile to figure out how to stop the messages, such as "copied 2 files" from being sent to stdout and shutting down the requesting application since it's not well-formed JSON. This answer explains how and has a link to Microsoft "Using command redirection operators". A /q in xcopy may or may not be necessary also, but certainly didn't do the job alone.
Thank you very much for any direction you may be able to provide.
The question that someone suggested as an answer and placed the little submission box on this question is one that I had already linked to in my question. I don't mean to be rude but, if it had answered my question, I would not have written this one. Thank you whoever you are for taking the time to respond, I appreciate it.
I don't see how that would be a better option than using system() because with the right parameters all the sub-directories and files of a single parent folder can be copied in one statement without having to iterate through all of them manually. Is there any reason why it would not be better to use system() apart from the fact that code will need to be different for each OS?
Handling errors are a bit different because system() doesn't return an errno but an exit code; however, the errors can be redirected from stderr to a file and pulled from there, when necessary
rename(): posix
_mkdir(): not posix. You want mkdir which is. mkdir takes two arguments, the second of which should usually be 077.
rmdir(): posix
remove(): posix
_stat(): not posix, you want stat() which is.
_stat and _mkdir are called as such on the Windows C library because they're not quite compatible with the modern Unix calls. _mkdir is missing an argument, and _stat looks like a very old version of the Unix call. You'll have trouble on Windows with files larger than 2GB.
You could do:
#ifdef _WIN32
int mkdir(const char *path, int mode) { return _mkdir(path); } /* In the original C we could have #defined this but that doesn't work anymore */
#define stat _stat64
#endif
but if you do so, test it like crazy.
In the end, you're going to be copying stuff with stdio; this loop works. (beware the linked answer; it has bugs that'll bite ya.)
int copyfile(const char *src, const char *dst)
{
const int bufsz = 65536;
char *buf = malloc(bufsz);
if (!buf) return -1; /* like mkdir, rmdir, return 0 for success, -1 for failure */
FILE *hin = fopen(src, "rb");
if (!hin) { free(buf); return -1; }
FILE *hout = fopen(dst, "wb");
if (!hout) { free(buf); fclose(hin); return -1; }
size_t buflen;
while ((buflen = fread(buf, 1, bufsz)) > 0) {
if (buflen != fwrite(buf, 1, buflen)) {
fclose(hout);
fclose(hin);
free(buf);
return -1; /* IO error writing data */
}
}
free(buf);
int r = ferror(hin) ? -1 : 0; /* check if fread had indicated IO error on input */
fclose(hin);
return r | (fclose(hout) ? -1 : 0); /* final case: check if IO error flushing buffer -- don't omit this it really can happen; calling `fflush()` won't help. */
}

How to open file using POSIX interface (open(),write())

I'm trying to open a file with the POSIX interface with the plan of then writing to it. However, I can't even get the file to open properly. I have checked similar questions but they don't seem to fix my problem.
So far I've got:
int file;
file = open(filename,O_CREAT | O_WRONLY);
// I tried open(filename,O_CREAT | O_WRONLY,0666) and other permission values to no avail
if(file == -1) {
return 0;
}
//then would go on to write...
I would think that this would work after looking at the other problems people have had, I've also tried to put other flags in (which I didn't really expect to make a difference since I should only need the two I have) and include different permissions but no matter what I do it gives me file == -1. Normally I would use a FILE object but that can't be used in this case.

Make a file to act as tty with dup

Okay, so I have a problem. I must get the output of a program using the execlp and make the output go directly to a file. The problem is that the program only outputs certain information if it's running in a tty,(I guess it calls isatty(3)).
Here is my code so far
void main(){
int fd = open("file", O_WRONLY | O_CREAT | O_TRUNC, 0755);
close(1);
dup(fd);
execlp("program","program",NULL);
close(fd);
}
I don't want to use OS commands like script (which works) or so on.
So the question is, how can I "trick" the program into thinking that it is writing into a tty?
Use a "pty" (Pseudo Terminal) as output. see this question for details.
Rachid Koucha wrote a lengthy article explaining the details how to work with ptys: Using pseudo-terminals (pty) to control interactive programs
Stop reading This text here just exists to stop the stupid SO algorithm to turn my answer into a comment. I hate it when software makes itself smarter than me :-(

Writing information from files into an archive file?

I'm a relatively decent Java programmer, but completely new to C. Thus some of these functions, pointers, etc are giving me some trouble...
I'm trying to create an archive file (I'm basically re-writing the ar sys call). I can fstat the files I want, store the necessary information into a struct I've defined. But now comes my trouble. I want to write the struct to the archive file. So I was thinking I could use sprintf() to put my struct into a buffer and then just write the buffer.
sprintf(stat_buffer, "%s", file_struct);
write(fd, stat_buffer, 60);
This doesn't appear to work. I can tell the size of the archive file is increasing by the desired 60 bytes, but if I cat the file, it prints nonsense.
Also, trying to write the actual contents of the file isn't working either...
while (iosize = read(fd2, text_buffer, 512) > 0) {
write(fd, text_buffer, iosize);
if (iosize == -1) {
perror("read");
exit(1);
}
}
I'm sure this is a relatively easy fix, just curious as to what it is!
Thanks!
%s is used to print string. So sprint will stop when it will meet a \0 character.
Instead, you could directly write your structure to your file. write(fd, &file_struct, sizeof(filestruct)); but you wont be able to read it with a cat call. You still can, from another unarchiver program, read the file content and store it to a structure read(fd, &filestruct, sizeof(filestruct));
This system is not perfect anyways, because it will store the structure using your computer endianess and wont be portable. If you want to do it right, check out the ar file format specification.

How to AllocConsole + Stdout redirect under cygwin

I have a complex >>cygwin<< windows application (aka. subsystem windows), and I want to add a debug console. I already tried the following variants, but none works for me.
The console appears with changed title, but remains dead-black, no output shown.
Variant 1)
ok = AllocConsole();
if (ok) {
h = GetStdHandle(STD_OUTPUT_HANDLE);
fd = _open_osfhandle((intptr_t)h, O_TEXT);
fp = _fdopen( fd, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
fprintf(stdout, "Hello worldd\n");
SetConsoleTitle("VM Debug");
}
Variant 2)
freopen("conout$","w",stdout);
fprintf(...
Variant 3)
freopen("/dev/conout","w",stdout);
fprintf(...
This may have been answered already many times, but none of the solutions worked for me.
Can anyone please help me?
But please keep in mind: it MUST be a cygwin problem and I need a cywin solution, as I know that one or the other variant works under MSVC or BorlandC.
Any answer helps, even one saying that cygwin is broken and there is no solution for me.
Yes, it is a cygwin problem. Cygwin's guys actually have worked hard to simulate as much as possible an "unix" environment, so the common W32 tricks can't work. You can anyway write your messages on the new console by using the WriteConsole function, but I see it isn't what you want. In the past I had a similar problem, ad solved it by creating a pipe(), redirecting it to stdout/stderr, and creating a thread that received characters from the pipe end wrote them to the new console via WriteConsole. Not easy.
Also, I think that the cygwin's console management has changed many times with the different versions, so maybe that a trick that seems to work with one version stops working wit another one.
It's a wild world...

Resources