Notification email in C program, via system call? or?

Hello everyone!
I'm quite new here, but this forum helped me a lot before without registering :slight_smile:
I'll go directly to my problem, I have been searching a bit about this issue but I was not successful.
I need to write a program in C code to notificate me (to my email) when some action is done (doesn't matter which, let's say when user login). I have tried to use using system call (system) this: echo "User has logged on." | mail -s "Notification" my@mail.com - this works nicely but it takes quite a lot of time (approx 1min) and I have to use system call inside C code - I think it's not an elegant way to do so. I need this to be almost realtime fast - I mean the action takes place and in let's say 3-5sec the mail is sent.
Is there any chance to solve this issue? It doesn't have to be with usage of system call, but I need to use it in C program. Any help is appreciated! Thanks, yours RoNNo

PS: English is not my mother tongue, so I apologize for it.

Moving thread to the programming area.

First, whatever is hanging the child processes you spawn off with your call to system() will probably cause the same problem no matter how you get around it.

Second, what the mail program does is pretty complex. Duplicating that would be a lot of work, and you won't do it as well as the mail program does.

Finding out why "echo ... | mail ..." is so slow is your best option.

If you're on Linux, run the mail utility under strace. If Solaris, use truss. Look at the man page for the one you need to use, then look in the output and find out where the mail program is taking so long.

Thanks for help, I have no experience with using strace, this is what it returns:

execve("/bin/echo", ["echo", "somthing"], [/* 23 vars */]) = 0
brk(0)                                  = 0x8a7b000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7813000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=70884, ...}) = 0
mmap2(NULL, 70884, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7801000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0000m\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1405508, ...}) = 0
mmap2(NULL, 1415592, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb76a7000
mprotect(0xb77fa000, 4096, PROT_NONE)   = 0
mmap2(0xb77fb000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x153) = 0xb77fb000
mmap2(0xb77fe000, 10664, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb77fe000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76a6000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb76a68d0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb77fb000, 8192, PROT_READ)   = 0
mprotect(0x804f000, 4096, PROT_READ)    = 0
mprotect(0xb7831000, 4096, PROT_READ)   = 0
munmap(0xb7801000, 70884)               = 0
brk(0)                                  = 0x8a7b000
brk(0x8a9c000)                          = 0x8a9c000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/locale.alias", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=2570, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7812000
read(3, "# Locale name alias data base.\n#"..., 4096) = 2570
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0xb7812000, 4096)                = 0
open("/usr/lib/locale/en_US.utf8/LC_IDENTIFICATION", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=373, ...}) = 0
mmap2(NULL, 373, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7812000
close(3)                                = 0
open("/usr/lib/gconv/gconv-modules.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=26048, ...}) = 0
mmap2(NULL, 26048, PROT_READ, MAP_SHARED, 3, 0) = 0xb780b000
close(3)                                = 0
open("/usr/lib/locale/en_US.utf8/LC_MEASUREMENT", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=23, ...}) = 0
mmap2(NULL, 23, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb780a000
close(3)                                = 0
open("/usr/lib/locale/en_US.utf8/LC_TELEPHONE", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=59, ...}) = 0
mmap2(NULL, 59, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7809000
close(3)                                = 0
open("/usr/lib/locale/en_US.utf8/LC_ADDRESS", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=155, ...}) = 0
mmap2(NULL, 155, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7808000
close(3)                                = 0
open("/usr/lib/locale/en_US.utf8/LC_NAME", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=77, ...}) = 0
mmap2(NULL, 77, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7807000
close(3)                                = 0
open("/usr/lib/locale/en_US.utf8/LC_PAPER", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=34, ...}) = 0
mmap2(NULL, 34, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7806000
close(3)                                = 0
open("/usr/lib/locale/en_US.utf8/LC_MESSAGES", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
close(3)                                = 0
open("/usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=57, ...}) = 0
mmap2(NULL, 57, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7805000
close(3)                                = 0
open("/usr/lib/locale/en_US.utf8/LC_MONETARY", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=286, ...}) = 0
mmap2(NULL, 286, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7804000
close(3)                                = 0
open("/usr/lib/locale/en_US.utf8/LC_COLLATE", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=1170770, ...}) = 0
mmap2(NULL, 1170770, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7588000
close(3)                                = 0
open("/usr/lib/locale/en_US.utf8/LC_TIME", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=2454, ...}) = 0
mmap2(NULL, 2454, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7803000
close(3)                                = 0
open("/usr/lib/locale/en_US.utf8/LC_NUMERIC", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=54, ...}) = 0
mmap2(NULL, 54, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7802000
close(3)                                = 0
open("/usr/lib/locale/en_US.utf8/LC_CTYPE", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=256324, ...}) = 0
mmap2(NULL, 256324, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7549000
close(3)                                = 0
fstat64(1, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7548000
write(1, "somthing\n", 9)               = 9
close(1)                                = 0
munmap(0xb7548000, 4096)                = 0
close(2)                                = 0
exit_group(0)                           = ?

Everything is done in sec, and it stops at exit_group(0) =
where is empty field, then here comes ? after about 1min and console is ready for use again.

It's waiting for a process to quit... Its return value is unknown because exit_group in fact has no return value.

I think you need to run strace -f to follow a process and its children.

When I run it with strace -f, it just returns the same. I'm kinda desperate, now normal echo message |mail -s "some subject" my@mail.com stopped to work even with delay, am I doing something wrong?

I can't tell without seeing your code.

I think you chopped off the interesting bits of your strace output, the "echo" may happen well after the mail process is created.

You're running strace on the echo, and not mail:

echo ... | strace ... mail ...

If mail is setuid, you may have to run as root. Also, use the strace option to record how long each system call takes - check the strace man page.