6

Is it okay, to wrap posix-commands in your program for stuff like remove, mkdir and copy, if the language doesn't provide this functionality to accomplish these, without having to implement them yourself and handle half a million edge-cases.

Comments
  • 2
    As long as you evaluate the result for success / failure, there's little reason to reinvent the wheel.

    Of course, you need to check whether the performance is enough on the targeted platforms under the targeted load scenarios. Especially if you ever should intend a Windows port because the preferred Windows method is creating threads, not processes which are much more expensive than under Linux.

    One of the exceptions would be iOS because apps can only be distributed via the app store, and Apple doesn't allow apps that start other programs.
  • 1
    @Fast-Nop
    Its going to be a linux cli-app.
  • 2
    @metamourge under Linux, it's not only likely to perform well, it's also in line with the traditional Unix philosophy of chaining stuff together. That's how shell scripting has always worked.

    Here some interesting performance data: https://bitsnbites.eu/benchmarking-...

    The data for Linux suggest that the OS itself was designed for such kind of usage.
  • 0
    I disagree with the other posts here. If the language does not support what you're trying to do, then you should use a different language that does support it.
  • 0
    @Gogeta70
    Well, do you know a language that supports copy, remove, mkdir and symlink.
    All with force-option.
    Copy, remove and remove with recursive.
    ?
  • 0
    @metamourge Sure, C or C++ can call library functions that perform those tasks.

    Edit: also, python has filesystem io libraries too, I believe.
  • 1
    @Gogeta70 C doesn't have such functions in its standard library, and the advice to use this as criterion for changing the project language is simply insane.
  • 0
    @Fast-Nop He said it was not possible in his chosen language. I never said it was a standard function in C, I just said it was possible in C.
  • 0
    @Gogeta70 yeah of course it's possible in C, with quite some extra code especially for corner cases and error handling.

    All while ignoring external tools that already exist, are known to work, are test hardened, and if they should have errors, that will be fixed by distro updates automatically.

    What are your arguments for ignoring these advantages?
  • 0
    @Fast-Nop Unless I misunderstood the question, he wants to do something like:

    system("mv src dest");

    That's bad practice in nearly all cases. Especially when Linux provides library functions with equivalent functionality.
  • 0
    @Gogeta70
    I need stuff like
    rm -rf a
    cp -rf a b
    ln -sf a b

    Stuff that is not necessarily implemented in the standard-library, especially the recursive parts.
  • 0
    @Gogeta70 So what would be the library for C here? C++ has std::filesystem, but C doesn't.

    Also, just saying it's "bad practice" is not an argument, that's just repeating the point. Especially if you think that it is so bad practice that this alone is worth switching the project language, there must be some severe points.
  • 0
    @metamourge @Fast-Nop Linux provides a filesystem API. To continue with my rename example, check the following.

    http://man7.org/linux/man-pages/...

    No programming language has every function as a standard. You have to use libraries to do a lot of stuff, including file IO.
  • 0
    @Gogeta70 C's library just doesn't include recursive copy. It would be worse to hand-roll a solution than to use something that exists, is tested, works, and is maintained.

    It MIGHT be that the performance could not be enough when starting external programs, but since it's easy to implement, it's also easy to benchmark under the relevant load scenarios.

    Besides, you were not able to state any reason why this is "bad practice", so this point rather looks like hear-say rumor with no factual basis.
  • 0
    @Fast-Nop The fact that you think it's a good idea to run a command and process the text output for errors shows a major lack of experience. It's pretty common knowledge that doing so is bad practice. You simply cannot handle errors properly in this manner.

    So what if it's not recursive? It's easy enough to implement. If you want everything written for you, then maybe programming isn't for you.

    What would you tell him if he had asked about socket programming? Tell him to run netcat as a system call and then parse the output?

    There are a handful of cases where it is proper to execute an external program to do a task but file system IO is not one of them.
  • 0
    @Gogeta70 Of course you get the result via the return value of the program.

    Trying to hack everything together oneself although it's readily available is only OK if it's either about the core parts of the application because then the point is to make something better than what's already available. Or if the available code is of dubious quality anyway. Or if licencing issues are in the way.

    I would wrap the system calls in some encapsulation wrapper so that it would be easy to change it later if need be and then focus on the actual application. That also helps time to market - delivery is an important feature, and the application must have it.
  • 0
    @Fast-Nop The problem is like I said before. You can't properly handle errors with system calls. There's a library function to do this for a reason.
  • 1
    @Fast-Nop I didn't have time to give a full response before, so here it is.

    I would not consider doing things the right way as hacking together code. Using system calls is hacky code, to be honest.

    You said you can check the return value of a system call to determine if there was an error, but it doesn't give you much, if any, information about what went wrong. You also have no opportunity to recover from the error.

    Time to market is important, but compromising the quality of the product is not a viable way to save time.
  • 0
    @Gogeta70 yes, the return codes are not as detailed. But quite frankly, what would you do if you can't copy a whole directory? You basically can't recover anyway in most of the scenarios because you can't fix the error cause. That leaves mainly deleting the partial copy and going back to the state before.

    As for the library functions like std::filesystem, they are there to have a uniform interface across platforms, and because spawning other processes can be expensive, namely under Windows, or even practically impossible, like under iOS. But in this case, the OP said portability does not play a role. Even if that should change later, that's not an issue when using wrapper functions.

    If using C++, I agree with you on going for std::filesystem because it's also already there, also well tested, also maintained.
  • 0
    @Fast-Nop I'm not talking about std::filesystem. If an OS provides an API to do something like move a file, it is best to use that API over a system call.

    Especially when advising someone new to programming, I think it's best to teach them the proper way to do something.
  • 0
    @Gogeta70 moving one file is fine, it's basically renaming. Copying directories is another issue, not least because you also need to decide what to do with links, so that's more special handling. The OS simply doesn't provide an API for copying directories, and the C standard library doesn't offer such a function either.

    But yeah, I get it that you would want to reinvent the wheel in order to achieve "cleanness" while I think that additional code just means additional bugs and additional cost.

    The whole point of good practice is to avoid additional bugs and additional cost. If observing good practice leads to additional code and additional bugs, I think it's bad practice.
  • 1
    @Fast-Nop I think we've come down to a difference of both preference and opinion. I like low-level code and prefer fine-grained control over what's happening in my code. It sounds like you prefer higher level languages (such as python, ruby, etc) where some of the implementation details are basically hidden.

    Along with avoiding bugs and reducing cost, I think good practice includes handling error conditions gracefully and writing self-documenting/readable code.

    I think we can both agree that instead of doing system("command") in C/C++, it would be more appropriate to use a language that abstracts away that functionality for you. In the case of Python, one could use Pathlib:

    https://docs.python.org/3/library/...
  • 1
    @Gogeta70 actually, I prefer C, have written much more complex recursive stuff than that and can develop bare metal when there is not even an OS so that I have to write the program loader myself - in assembly. So it's not as if I were afraid of rolling such solutions. From a "what I would like" point of view, I'm even with you.

    But I've been in the industry for decades and also think about what's good investment of scarce dev time. What I don't agree with is choosing the project language on the basis of such a minor detail.

    But nevertheless, thanks for an actually tech oriented discussion here on DR. ^^
Add Comment