I'm trying to add 3 system calls in FreeBSD to set acl for a file in UFS2.
int setacl(char *name, int type, int idnum, int perms);
int clearacl(char *name, int type, int idnum);
int getacl(char *name, int type, int idnum);
Would someone please tell me how to get started?
A quick google search for 'freebsd ufs2 acls' yields this page:
http://www.freebsd.org/doc/handbook/fs-acl.html
You will probably want to read that page to discover that ufs2 acls already exist, and to learn a bit more about the implementation.
If you're looking for a generic start on FreeBSD kernel hacking, you may want to see if anyone has kept the 'junior kernel hacker' list up to date. Poul-Henning Kamp used to update it ever summer, just in time for the Google Summer of Code announcements.
Related
Let say we have a function:
void persist_result(FILE* to, unsigned char* b, int b_len) {...}
which would save some result in the given FILE* to.
Now I would like to get the data before the data is written to to, do something with it (assume encrypt it, etc..) and then call the actual IO operation, directly or indirectly.
One solution could be setting a buffer, but I don't know how to trigger my method for the encryption operation.
Also I was thinking to get some handle of file in memory, but don't know if there is any ISO way to do that?
Or any better solution?
Consider the following:
Size of the data need to be written by the persist_result is unknown, it could be 1 or more bytes.
I cannot change the source of persist_result.
No C++; it must be a portable C solution.
What you are looking for is the Observer Pattern.
When your function is called, actually you can first capture that call, do whatever you prefer and then continue with what you were doing. You could implement it in C using pointer to functions.
You can get inspiration from the following example
There is no way to capture every operation in standard C without changing the calls. Things like encryption need context (like key) to work; that complicates life in general, but maybe persist_result() handles that automatically. How will you handle things like fseek() or rewind()?
I think you are in for a world of pain unless you write your I/O operations to a non-standard C API that allows you to do what's necessary cleanly. For example, your code might be written to call functions such as pr_fwrite(), pr_putc(), pr_fprintf(), pr_vfprintf(), pr_fseek(), pr_rewind(), etc — you probably wouldn't be applying this to either stdin or stdout — and have those do what's necessary.
If I were going to try this, I'd adopt prefixes (pr_ and PR) and create a header "prstdio.h" to be used in place of, or in addition to, <stdio.h>. It could contain (along with comments and header guards, etc):
#include <stdarg.h>
// No need for #include <stdio.h>
typedef struct PRFILE PRFILE;
extern PRFILE *pr_fopen(const char *name, const char *mode);
extern int pr_fclose(PRFILE *fp);
extern int pr_fputc(char c, PRFILE *fp);
extern size_t pr_fwrite(const void *buffer, size_t size, size_t number, PRFILE *fp);
extern int pr_fprintf(PRFILE *fp, char *fmt, ...);
extern int pr_vfprintf(PRFILE *fp, char *fmt, va_list args);
extern int pr_fseek(PRFILE *fp, long offset, int whence);
extern void pr_rewind(PRFILE *fp);
…
and all the existing I/O calls that need to work with the persist_result() function would be written to use the prstdio.h interface instead. In your implementation file, you actually define the structure struct PRFILE, which would include a FILE * member plus any other information you need. You then write those pr_* functions to do what's necessary, and your code that needs to persist results is changed to call the pr_* functions (and use the PRFILE * type) whenever you currently use the stdio.h functions.
This has the merit of being simply compliant with the C standard and can be made portable. Further, the changes to existing code that needs to use the 'persistent result' library are very systematic.
In a comment to the main question — originally responding to a now-deleted comment of mine (the contents of which are now in this answer) — the OP asked:
I need to do the encryption operation before the plain data write operation. The encryption context is ready for work. I was thinking using the disk on memory, but is it ISO and can be used in Android NDK and iOS too?
Your discussion so far is in terms of encrypting and writing the data. Don't forget the other half of the I/O equation — reading and decrypting the data. You'd need appropriate input functions in the header to be able to handle that. The pr_ungetc() function could cause some interesting discussions.
The scheme outlined here will be usable on other systems where you can write the C code. It doesn't rely on anything non-standard. This is a reasonable way of achieving data hiding in C. Only the implementation files for the prstdio library need know anything about the internals of the PRFILE structure.
Since 'disk in memory' is not part of standard C, any code using such a concept must be using non-standard C. You'd need to consider carefully what it means for portability, etc. Nevertheless, the external interface for the prstdio library could be much the same as described here, except that you might need one or more control functions to manipulate the placement of the data in memory. Or you might modify pr_fopen() to take extra arguments which control the memory management. That would be your decision. The general I/O interface need not change, though.
On Linux, sched.h contains the definition of
int sched_rr_get_interval(pid_t pid, struct timespec * tp);
to get the time slice of a process. However the file shipping with OS X El Capitan doesn't hold that definition.
Is there an alternative for this on OS X?
The API's related to this stuff are pretty byzantine and poorly documented, but here's what I've found.
First, the datatypes related to RR scheduling seem to be in /usr/include/mach/policy.h, around line 155. There's this struct:
struct policy_rr_info {
...
integer_t quantum;
....
};
The quantum is, I think, the timeslice (not sure of units.) Then grepping around for this or related types defined in the same place, I found the file /usr/include/mach/mach_types.def, which says that the type struct thread_policy_t contains a field policy_rr_info_t on line 203.
Next, I found in /usr/include/mach/thread_act.h the public function thread_policy_get, which can retrieve information about a thread's policy into a struct thread_policy_t *.
So, working backwards. I think (but haven't tried at all) that you can
Use the thread_policy_get() routine to return information about the thread's scheduling state into a thread_policy_t
That struct seems to have a policy_rr_info_t sub-substructure
That sub-structure should have a quantum field.
That field appears to be the timeslice, but I don't know about the units.
There are no man pages for this part of the API, but this Apple Developer page explains at least a little bit about how to use this API.
Note that this is all gleaned from just grepping the various kernel headers, and I've definitely not tried to use any of these APIs in any actual code.
The Linux kernel manpages declare the epoll_ctl procedure as follows:
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
As evident, the event parameter is declared as a pointer to the epoll_event struct.
The significance of said observation in the context of this question is that there is no const ahead of the pointer type declaration, and thus, the procedure appears to be permitted to modify the contents of the passed structure.
Is this an omission of sorts, or was the procedure made like that by design and we have to assume that the passed structure may indeed be modified inside the procedure?
I understand that the declaration is unambiguous here, but is there reason to believe this to be an omission?
I have also taken a look at the relevant source code in kernel 4.6 tree, and I don't see much evidence that the procedure even intends to modify the structure, so there.
Found a rather conclusive answer on the Linux mailing list. Quoting Davide Libenzi here, chief or sole author of "epoll":
From: Davide Libenzi <davidel <at> xmailserver.org>
Subject: Re: epoll_ctl and const correctness
Newsgroups: gmane.linux.kernel
Date: 2009-03-25 16:23:21 GMT (7 years, 17 weeks, 1 day, 9 hours and 4 minutes ago)
On Wed, 25 Mar 2009, nicolas sitbon wrote:
Currently, the prototype of epoll_ctl is :
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
I searched in the man of epoll_ctl and google, and it seems that the
structure pointed to by event isn't modify, valgrind confirms this
behaviour, so am I wrong? or the good prototype is
int epoll_ctl(int epfd, int op, int fd, struct epoll_event const *event);
According to the current ctl operations, yes. But doing that would prevent
other non-const operations to be added later on.
Davide
The takeaway is that even though de-facto behavior is not to modify the structure, the interface omits const modifier deliberately because other control operations may be added in the future through the same system call, necessitating a potentially modifiable structure pointed at by the event argument.
I should have hit the kernel mailing list first, apologies for another perhaps redundant information on SO. Leaving the question and this answer for posterity.
typedef struct _iobuf{
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
} FILE;
I try to print them but I don't understand what they mean.
Here What exactly is the FILE keyword in C? He said "Some believe that nobody in their right mind should make use of the internals of this structure." but he didn't explain what they mean.
Look at the source code for your system's run-time libraries that implement the FILE-based IO calls if you want to know what those fields mean.
If you write code that depends on using those fields, it will be non-portable at best, utterly wrong at worst, and definitely easy to break. For example, on Solaris there are at least three different implementations of the FILE structure in just the normal libc runtime libraries, and one of those implementations (the 64-bit one) is opaque and you can't access any of the fields. Simply changing compiler flags changes which FILE structure your code uses.
And that's just one one version of a single OS.
_iobuf::_file can be used to get the internal file number, useful for functions that require the file no. Ex: _fstat().
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I was making a code and I had like 5 include files in there, I was defining functions in this file and then realized why should not I just make separate header files for all the functions and then just include them in a file at last. But, I have seen that this is not done usually. Why not? Is there a particular disadvantage of doing this?
This is not a real answer, because the question has a wrong assumption:
But, I have seen that this is not done usually.
This is not true. This is a common practice. A good example is ffmpeg.h. The header is a front-end to an extensive library.
The argument of long compilation times is bogus. Today the systems are very fast. This is only important for really huge systems, but I really don't think that you work with them. I never encountered such systems myself.
And compilation times aren't execution times. This is another misconception.
For your convenience the whole code of ffmpeg.h:
#ifndef _INCLUDE_FFMPEG_H_
#define _INCLUDE_FFMPEG_H_
#ifdef HAVE_FFMPEG
#include <avformat.h>
#endif
#include <stdio.h>
#include <stdarg.h>
/* Define a codec name/identifier for timelapse videos, so that we can
* differentiate between normal mpeg1 videos and timelapse videos.
*/
#define TIMELAPSE_CODEC "mpeg1_tl"
struct ffmpeg {
#ifdef HAVE_FFMPEG
AVFormatContext *oc;
AVStream *video_st;
AVCodecContext *c;
AVFrame *picture; /* contains default image pointers */
uint8_t *video_outbuf;
int video_outbuf_size;
void *udata; /* U & V planes for greyscale images */
int vbr; /* variable bitrate setting */
char codec[20]; /* codec name */
#else
int dummy;
#endif
};
/* Initialize FFmpeg stuff. Needs to be called before ffmpeg_open. */
void ffmpeg_init(void);
/* Open an mpeg file. This is a generic interface for opening either an mpeg1 or
* an mpeg4 video. If non-standard mpeg1 isn't supported (FFmpeg build > 4680),
* calling this function with "mpeg1" as codec results in an error. To create a
* timelapse video, use TIMELAPSE_CODEC as codec name.
*/
struct ffmpeg *ffmpeg_open(
char *ffmpeg_video_codec,
char *filename,
unsigned char *y, /* YUV420 Y plane */
unsigned char *u, /* YUV420 U plane */
unsigned char *v, /* YUV420 V plane */
int width,
int height,
int rate, /* framerate, fps */
int bps, /* bitrate; bits per second */
int vbr /* variable bitrate */
);
/* Puts the image pointed to by the picture member of struct ffmpeg. */
void ffmpeg_put_image(struct ffmpeg *);
/* Puts the image defined by u, y and v (YUV420 format). */
void ffmpeg_put_other_image(
struct ffmpeg *ffmpeg,
unsigned char *y,
unsigned char *u,
unsigned char *v
);
/* Closes the mpeg file. */
void ffmpeg_close(struct ffmpeg *);
/*Deinterlace the image. */
void ffmpeg_deinterlace(unsigned char *, int, int);
/*Setup an avcodec log handler. */
void ffmpeg_avcodec_log(void *, int, const char *, va_list);
#endif /* _INCLUDE_FFMPEG_H_ */
Some people argue that putting functions in a separate file and including them through a header adds some overhead to the project and increases compilation (not execution) time. Although strictly speaking this is true, in practice the increased compilation time is negligible.
My take on the issue is more based on the purpose of the functions. I am against putting a single function per file with an associate header as this quickly becomes a mess to maintain. I do not think that putting everybody together in a single file is a good approach either (also a mess to maintain, although for different reasons).
My opinion is that the ideal trade off is to look at the purpose of the functions. You should ask yourself whether the functions can be used somewhere else or not. In other words, can these functions be used as a library for a series of common tasks in other programs? If yes, these functions should be grouped in a single file. Use as many files as you have general tasks. For instance, all functions to perform numerical integration in one file, all functions to handle file i/o in another, all functions to deal with strings in a third file and so on. In this way your libraries are consistent.
Finally, I would place a function that performs a task only meaningful for a specific program into the same file of the main function. For instance any function whose purpose is to initialize a series of variables.
But most of all, you should take any advice just as an advice. In the end of the day you should adopt the approach that makes your (or your team) development the most productive.
You should only make one "super-include-header" if you are writing some sort of API or library and want to make it easy for the user of that library to access the functions inside. The Windows OS API is the most obvious example of this, where one #include gives you access of thousands upon thousands of functions.
But even when writing such libraries, you should be wary of "super-headers". The reason why you should try to avoid them is related to program design. Object-oriented design dictates that you should strive to make isolated, autonomous modules that focus on their own task without knowing or caring about the rest of the program.
The rationale behind that design rule, is to reduce the phenomenon known as tight coupling, where every module is heavily dependant on other modules. Computer science research (like this study, for example) shows that tight coupling combined with complexity leads to far more software errors, and also far more severe errors. If a program with tight coupling gets a bug in one module, the bug might escalate throughout the whole program and cause disaster. While a bug in one autonomous module with loose coupling only leads to that particular module failing.
Each time you include a header file, you create a dependency between your program and that header file. So while it is tempting to just make one file that includes everything, you should avoid this, as it would create tight coupling between all modules in the project. It will also expose the modules to each other's global name space, possibly leading to more name space collisions with identical variable names etc.
Tight coupling is also, aside from the safety concerns, very annoying when you link/build your program. With tight coupling, suddenly your database module cannot work if something completely unrelated, like the GUI library isn't linked.