I'm working on tool to allow you to easily change your Trackpoint settings on the Lenovo thinkpads. The little nipple. I'm writing it in C to help me learn the language more. I'm having a problem I can't quite put my paw on.

The code responsible for changing the setting is:

int set_nipple_speed(int speed) { if (speed <= 0) { printf("Invalid value %d speed must be greater than 0", speed); return 1; } char command[100]; char * path = get_trackpoint_path(); sprintf(command, "echo %d | sudo tee %s/serio2/speed", speed, path); return system(command); }
I'm getting:
tee: /sys/devices/platform/i8042/serio1: Is a directory 33 sh: 2: /serio2/speed: not found
Oh and theres a function being called to get the base path to get to the trackpoint settings:
char *get_trackpoint_path() { FILE *pipe_stream = popen("find /sys/devices/platform/i8042 -name name | xargs grep -Fl " "TrackPoint | sed 's/\\/input\\/input[0-9]*\\/name$//'", "r"); char path[2048]; if (pipe_stream == NULL) { printf("Failed to run command to find trackpoint path"); return NULL; } fgets(path, sizeof(path), pipe_stream); pclose(pipe_stream); char *path_ptr = path; return path_ptr; }
Would anyone be willing to help me
#debug this? I'm pretty new to C. Project is here #codinghelp

I seems like the string in command is being cut off. The /serio2/speed is getting cut off for some reason. #codinghelp
@Froogal Is it because you're returning the pointer from the path function and then not using the syntax to get the value the pointer resolves to?
@KayOhtie If I change sprintf(command, "echo %d | sudo tee %s/serio2/speed", speed, path);

to
sprintf(command, "echo %d | sudo tee %s/serio2/speed", speed, *path); it only grabs the first character. I was wondering if a null terminator is hiding in the string because get_trackpoint_path() is returning /sys/devices/platform/i8042/serio1, but /serio2/speed is getting cut off.

@Froogal Might be given it's taking terminal output that is probably not designed for a C application to make use of in a not-displayed-text way. You could also try swapping the -F1 to -FL1 to lop off the match portion, so you're just given the path.

Probably better at that point to do string ops within C itself for predictability.

@KayOhtie I fixed it by using snprintf() over sprintf().
@KayOhtie WAIT I think I fucked up lol
@KayOhtie
```
Command to run:
Nipple speed set to 30
```
The output above should have something like
echo 30 | tee /path/to/the/nipple

I think it got rid of the error but I'm getting undefined behavior.

@Froogal I don't know for sure, but using C as effectively a replacement for what would normally be Perl or a bash script, which are far looser around things, might have something to do with it.

I assume this has already been mocked up in bash first, but it might be a case of using the right mechanisms to fopen/fwrite/fclose. I'm always really leery of using any language to run shell commands that would normally just be scripted with something else, when the language used has the mechanisms you need.

@Froogal Like I think learning C is a good idea, but I _personally_ feel that treating it like bash or Perl isn't really learning C so much as how to write C like bash, instead of to write C like C.

This is not to discourage using C here at all, but instead to encourage learning how to do this the way you'd normally want to in C :3

@KayOhtie I know what you mean, and thats one of the reasons im doing this. I have no idea how I would want to do this in C. This will eventually be an extremely simple gui tool, im working on the "backend" to get the functionality down. Then try torturing myself with some gui development with C with Clay. I figure the best way to learn C is to just SHOVE it in my brain lol. I do have a shell script written but I would use Python if anything else for gui support.

@Froogal You could always start by writing it fully in Python with no shell/system() calls at all to map out doing it more in a programming language than using bash scripting style, and then work on learning C with that. It'd be structured more in the way a non-scripting language would be at that point.

EDIT: To add, I think the hardest part is that C is such a low-level-ish "high-level" language that going from "bash scripting" to "Now it's C" is a much larger jump than "I built this out completely in Python's standard library/modules with minimal PyPi dependencies and now I've a closer-to-C structure to work on learning it with".

@KayOhtie Python would be the best language for this right? The vast majority of distros ship with Python, if not most linux users install it. I chose C also for portability between distros. Shell script of course would also run on all/most distros, maybe I should create a cli tool written in bash to use from C. Kinda like what im doing but instead of just calling tee and such in C that would be called from the cli app?

@Froogal From the shell script? Sure, could just distribute it easily as-is, especially since I assume it has few dependencies.

As far as GUI app... that's hard to say for sure. Python tends to be readily available, and as long as you're using standard library modules you're probably set and don't need anything weird packaging-wise. But even then if you do need some GUI library or other thing you could always make it a dependency to be installed, it just then couldn't be as simple as downloading the .py file and "sudo python myscript.py"

@KayOhtie Im coming from c++ and Rust, then from that web development is where I started. Ive been learning C on and off for years but Rust helped me understand more low level concepts but I figured its time to try again.