HN user

rian

212 karma

love to code

Posts15
Comments78
View on HN

Might I recommend not using the prev/next executables and instead adding another directory level to indicate search page, e.g. ytfs/search/1/video.mp4

would make it easy to reexport this file system, e.g. Over http or smb.

I think it's a safe assumption that most Netflix subscribers want to watch Netflix on their TV with ease.

My grandpa has a Netflix account. If he wants to buy a tv that can play Netflix, It's so much easier for me to tell him "buy a TV with the Netflix logo" than "buy a TV and then buy either chromecast/Apple tv/roku."

Just because literally everyone you know uses those platforms doesn't mean they have meaningful pull either. That's unless you know every TV owner in the world. Your anecdotal experience is irrelevant compared to the average experience of the hundreds of millions of TV owners across the country and world.

Most Netflix subscribers (edit from people) just want to watch Netflix on their TV. If you're buying a new TV, the easiest way to do that is to get one that supports Netflix out of the box.

Or in other words

The way you feel when you can't use GPL code in your startup

Is the same way I feel when I can't use Mickey Mouse or Mario for a toy in my toy company.

That doesn't mean you have to support every particular choice about how it is wielded

I never wrote you have to support how it's wielded but that it is wielded. Your freedom of speech analogy doesn't apply to what I wrote.

I agree with your last point, but I think that's exactly the job of lawmakers. Once you've found an abuse of the law, you refine the law. You don't just throw your hands up and say "well the pros outweigh the cons." Legislation isn't futile. In this specific case, copyright law has only grown more powerful without any significant negative feedback.

All I'm saying is, if you feel there is something wrong with the GPL, well it's not the only instance of copyright abuse and maybe you should focus on copyright law itself, not the GPL.

It's possible but it's not logical!

If one supports the level of power that current copyright law provides for authors, then you must support the fact that any particular author wields it. If you think the author is abusing power, then that means the current copyright law is too broad, and if it's too broad you ultimately don't agree with the law.

C++ templates do have "protocols," they just aren't necessary. The result is that the perpetrator of a template error is ambiguous.

check out type traits: http://en.cppreference.com/w/cpp/types and std::enable_if: http://en.cppreference.com/w/cpp/types/enable_if

"concepts lite" is a proposal to add syntactic sugar for type traits as well as enhance them a bit.

in general this is how C++ does things now: first add library-level solutions as far as possible, then add language-level syntactic sugar once the usage and implementation is fully understood.

reinterpret_cast<>?! that's implementation-defined. not to mention type-aliasing which is undefined behavior. what you want is:

    template<typename T>
    typename std::enable_if<std::is_trivial<T>::value, T>::type
    getValue(std::array<char, sizeof(T)> bytes) {
        T toret;
        std::memcpy(&toret, bytes.data(), sizeof(toret));
        return toret;
    }
there is no-performance hit compared to your function. this is a type-safe and well-defined version of the function above.

btw, was your usage of trivial a pun? if so, that's amazing. we need more type traits puns.

On your Mac the stack trace hints that the bug is due to a bad pointer/offset/size being passed to fwrite() but in the debug builds it looks like it's in the fastcmp() function. Is this the descrepancy you're talking about in the final paragraph?

It's not a false contradiction (dichotomy?). In general, non-standard modifications can break the default configuration, even in your hotplug example. If they can break the default configuration, I'm simply saying don't complain when they do.

The OP is running GNOME and complaining because he's not using systemd and it broke something (non-standard configuration) and because he can't understand the d-bus-controlled cgroups system (complicated system internals).

To all the programmers saying they don't want to spend their time building their own desktops:

My point isn't that people in general should be hacking up their own Linux desktops, even if they can. Programmers that like to do that probably should though.

My point is that if you are going to commit to using user-oriented systems like GNOME/KDE, don't do non-standard things and don't complain because system internals seem too complicated. They aren't meant to be hackable/simple!

Kudos to you sir for contributing!

By "core contributor" I did mean developer but really my point was that there is an explicit gap in the roles of the people involved in these platforms. You have a small group of people explicitly focused on development, and a much larger group of people explicitly focused on usage. Windows and Mac OS X are in the same situation. The best strategy for the people developing these platforms is to focus on a generally applicable UI to accomodate the large heterogeneous group. Ultimately this will result in the platform being more omakase (if you will) and less likely to be everything for everybody, though a decent default.

I don't mean to say that this is a fault with GNOME/KDE themselves but more of a likely unavoidable consequence when you build a product for a large general audience.

If you're a programmer this is really annoying. When something is broken or annoying to you, you have the ability to fix it but because there is so much organization/process/design around these systems, the activation energy is too high.

But if you're a programmer you don't have to deal with this. You can just use a simpler system meant for hackability, a system where the users are the developers.

I see nothing wrong with big vertically integrated Linux systems like GNOME/KDE and in fact I'm glad they exist. If they did not, I would not be able to genuinely recommend Linux to my non-technical friends. Apple has shown the vertical integration is an efficient and successful way to design products for large groups of people, not unsurprising that those systems are mimicking that.

I don't understand technical Linux users who use GNOME/KDE. They are not designed to be hackable nor modular. They are intended for enterprise users who want something Windows-ish. Their core contributors aren't volunteers/users, they're people who are paid by Red Hat and SuSE.

If you're a technical user/programmer and you want something more minimal, simple, hackable, then don't use GNOME/KDE. Use xmonad or dwm, they are written by programmers for programmers. They are literally only window managers, nothing else. Only what you put in your .Xsession is what gets started when you run startx.

Sure, you don't get a file manager or auto-mounting of usb drives out of the box, that's because no sane programmer would want that by default. If you are one of the few that do, then install udisks and configure it the way you like (e.g. mount specific usb drives to specific locations with specific permissions). As a programmer you'll ultimately be happier. I promise.

Debian doesn't get in the way. It fully supports customization at this level. Take advantage of it!

it only works because you're skipping over environment variables:

    char **argv = &stack;
    char **envp = __environ = argv + ( 1 * sizeof( void* ) );
let's say argv = 0x8, then according to this code, on x86_64, envp = 0x48 (0x8 + sizeof(void * ) * sizeof(char *)). here's a sample stack where argc = 1:
    stack:
    [0x0]  = 1 (argc)
    [0x8]  = "program path"
    [0x10] = 0
    [0x18] = "FOO1=FOO1"
    [0x20] = "FOO2=FOO2"
    [0x28] = "FOO3=FOO3"
    [0x30] = "FOO4=FOO4"
    [0x38] = "FOO5=FOO5"
    [0x40] = "FOO6=FOO6"
    [0x48] = "FOO7=FOO7"
    ...
since you set envp to 0x48 it now points to FOO7=FOO7, you've inadvertently skipped FOO1-FOO6. if argc = 2, then envp would point to FOO6 and you skipped FOO1-FOO5.

try this with your code, pass 8 arguments to your test. the environment will point to the last element in argv and then terminate, completely missing the actual environment. again, that's only the behavior on x86, on x86_64, passing any argument will cause a segfault.

good point, the gcc optimizer is smart enough to omit the preamble. it's still hacked though. inline assembly is one thing, messing with compiler-owned registers is another especially without a clobber list. btw why do you prefix your x84_64 start code with "mov %rsp,%rbp"? "xor %ebp, %ebp" is more idiomatic and efficient.

according to the abi (http://www.x86-64.org/documentation/abi.pdf), the stack frame is set up like this:

    argc = [RSP+0]
    argv = RSP+8
    envp = RSP+8+8*argc+8
the same for x86 but replace 8 with 4. your code mirrors this but retrieves argv by taking the address of the second function argument (because you pass [RSP+8] to __init(), which is actually argv[0]). C provides no guarantees on the stability of addresses of passed argument values between caller and callee, so this makes your code subject to non-standard behavior. i can see this working for x86 since values as passed through the stack but not for x86_64 where values are passed through registers.

if you're seeing bugs between gcc -O3 and -Os it's likely due to that, or it's due to improper use of inline assembly/clobbering registers.

00_start.c is too hacked on x86_64. it'll work but you're getting a less efficient binary since gcc has to assume _start is called like a normal C function (e.g. it creates a preamble). you should just implement it in assembly.

__init() itself also needs some work. the argument list is weird, linux pushes all of argc, argv, and environ on the stack. why special case argc? also your method of deriving argv and environ from the function argument's address is extremely brittle, and i don't think it actually works on x86_64 (if it does, that's really lucky). you aren't calculating envp using argc, so it's probably wrong. you could get more efficient code from using __attribute__((noreturn)). this would be better:

    /* called from _start */
    void __init(void *initial_stack) __attribute__((noreturn));    
    void __init(void *initial_stack) {
        int argc = *(int *) initial_stack;
        char **argv = ((char **) initial_stack) + 1;
        /* assert(!argv[argc]); */
        char **envp = __environ = argv + argc + 1;

        _exit(main(argc, argv, envp));
    }

Just curious, how would you describe what most people usually mean by "callbacks"?

I've always considered function arguments to functions like qsort() as callbacks, and from my interpretation of Wikipedia it seems to agree. Now I wonder if my interpretation has been overly general or if a more specific interpretation has become more commonplace.

Maybe inherently was the wrong word. Though you can imagine a logger API that was like this:

    typedef enum {
        CONSOLE_LOGGER,
        DATABASE_LOGGER,
        /* etc. */
    } LoggerType;

    void add_logger(LoggerType);
In this API you're constrained by what loggers you can add. It's not the totally unchecked free-for-all that a callback-based API provides. The user is strictly unable to shoot themselves in the foot.

But this limits the expressive power that callbacks provide. Sorry I don't have any other API recommendations. The only way I can think of to stay expressive while safeguarding against unintended abuse is to include code analysis.

Yes, the core issue in the database logger example is that it's a circular dependency.

The point of the article is that callback-based APIs like this obscure the actual problems (like circular dependencies).

You're right that constrained designs prevents issues like these but callback-based APIs aren't inherently constrained. They allow anything to happen, which is why they conversely encourage errors like these (and are subject to pitfalls).

Yeah problems with mutexes are ultimately the fault of the programmer.

The point that the article is trying to make is that because callback APIs don't expose their correctness requirements and because their correctness requirements are externally defined, they encourage programming error like this.