473,797 Members | 2,955 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

using write() instead of puts() in a trivial program?

Greetings,

I hope my greenness isn't showing too bad by asking this, but I ran across
this trivial program today that left me flabbergasted:

#define MESSAGE "This account is currently not available.\n"

int
main(int argc, char *argv[])
{
write(STDOUT_FI LENO, MESSAGE, sizeof(MESSAGE) );
_exit(1);
}

This is an excerpt from the newly-rewritten nologin(8) in FreeBSD. I am
not willing to accept that the person who committed this code is a fool,
thus I have to conclude that I just don't understand why exactly the
following isn't good enough for such a trivial program:

puts("This account is currently not available.");

Perhaps write() would be appropriate in a program which did intensive
amounts of output, but the meat of this program is literally 1 line long.

I tried doing a Google search, but as you can imagine, the commonality of
the "write" keyword throws off any results that might be useful, so I was
wondering some kind, generous person here could clue me in on what's going
on here. I'd greatly appreciate it.

Charles Ulrich
Nov 14 '05 #1
24 5868
Charles Ulrich <NO***@bloodyse curenym.spamnet > scribbled the following:
Greetings, I hope my greenness isn't showing too bad by asking this, but I ran across
this trivial program today that left me flabbergasted: #define MESSAGE "This account is currently not available.\n" int
main(int argc, char *argv[])
{
write(STDOUT_FI LENO, MESSAGE, sizeof(MESSAGE) );
_exit(1);
} This is an excerpt from the newly-rewritten nologin(8) in FreeBSD. I am
not willing to accept that the person who committed this code is a fool,
thus I have to conclude that I just don't understand why exactly the
following isn't good enough for such a trivial program: puts("This account is currently not available."); Perhaps write() would be appropriate in a program which did intensive
amounts of output, but the meat of this program is literally 1 line long. I tried doing a Google search, but as you can imagine, the commonality of
the "write" keyword throws off any results that might be useful, so I was
wondering some kind, generous person here could clue me in on what's going
on here. I'd greatly appreciate it.


If this is supposed to be a program that, when used for a user's shell,
displays the notice and then terminates, then I have to share your
confusion. Using a simple puts() call instead of a non-standard write()
call, even followed with a non-standard _exit() call, would have been
much simpler. Perhaps you could track down the writer of this program
and ask him why he wrote it that way?

--
/-- Joona Palaste (pa*****@cc.hel sinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Show me a good mouser and I'll show you a cat with bad breath."
- Garfield
Nov 14 '05 #2
begin followup to Charles Ulrich:
int
main(int argc, char *argv[])
{
write(STDOUT_FI LENO, MESSAGE, sizeof(MESSAGE) );
_exit(1);
}
write(2) is a system call.
_exit(2) is a system call.
[...] I just don't understand why exactly the following isn't
good enough for such a trivial program:

puts("This account is currently not available.");


puts(3) is part of the C run time library.

By using nothing but system calls the total size of the resulting
binary can be minimized. See option -nostdlib of gcc.

--
Für Google, Tux und GPL!
Nov 14 '05 #3

"Joona I Palaste" <pa*****@cc.hel sinki.fi> wrote in message
news:bt******** **@oravannahka. helsinki.fi...
If this is supposed to be a program that, when used for a user's shell,
displays the notice and then terminates, then I have to share your
confusion. Using a simple puts() call instead of a non-standard write()
call, even followed with a non-standard _exit() call, would have been
much simpler. Perhaps you could track down the writer of this program
and ask him why he wrote it that way?


Probably links in less code? Let's try this out

test1.c
#include <stdio.h>
int main(void) { puts("hello world"); return 0; }

vs.

test2.c
#include <unistd.h>
int main(void) { write(0, "hello world\n", 12); return 0; }

vs.

test3.c
#include <stdio.h>
int main(void) { printf("hello world\n"); return 0; }

All compile and execute fine in Linux... [compiled with -O2 -s]

tombox root # ls -l test?
-rwxr-xr-x 1 root root 3020 Jan 12 15:43 test1
-rwxr-xr-x 1 root root 3040 Jan 12 15:43 test2
-rwxr-xr-x 1 root root 3020 Jan 12 15:46 test3

So it turns out puts/printf is smaller ;-)

I guess the BSD guy either had a really specific reason [e.g. part of the
kernel? not in this case...] since puts is simpler and smaller!

Personally I'd just printf since I use it for all output ;-)

Tom

Nov 14 '05 #4
Charles Ulrich <NO***@BLOODYse curenym.SPAMnet > writes:
I hope my greenness isn't showing too bad by asking this, but I ran across
this trivial program today that left me flabbergasted:

#define MESSAGE "This account is currently not available.\n"

int
main(int argc, char *argv[])
{
write(STDOUT_FI LENO, MESSAGE, sizeof(MESSAGE) );
_exit(1);
}

This is an excerpt from the newly-rewritten nologin(8) in FreeBSD.

[...]

Presumably the FreeBSD nologin program doesn't need to be portable to
anything other than FreeBSD. Given that constraint, I suppose there's
not much advantage in using the portable puts() rather than the
relatively non-portable write().

Having said that, it's not how I would have written it. puts() or
printf() would make for more legible code.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #5
Charles Ulrich <NO***@BLOODYse curenym.SPAMnet > wrote in
news:pa******** *************** *****@BLOODYsec urenym.SPAMnet:
Greetings,

I hope my greenness isn't showing too bad by asking this, but I ran
across this trivial program today that left me flabbergasted:

#define MESSAGE "This account is currently not available.\n"

int
main(int argc, char *argv[])
{
write(STDOUT_FI LENO, MESSAGE, sizeof(MESSAGE) );
_exit(1);
}

This is an excerpt from the newly-rewritten nologin(8) in FreeBSD. I
am not willing to accept that the person who committed this code is a
fool, thus I have to conclude that I just don't understand why exactly
the following isn't good enough for such a trivial program:

puts("This account is currently not available.");

Perhaps write() would be appropriate in a program which did intensive
amounts of output, but the meat of this program is literally 1 line
long.

I tried doing a Google search, but as you can imagine, the commonality
of the "write" keyword throws off any results that might be useful, so
I was wondering some kind, generous person here could clue me in on
what's going on here. I'd greatly appreciate it.

Charles Ulrich


Finding an answer to such silly problem is the same as asking and trying
to find an answer to a problem like "I have to go to the shop which is
across a street, I chose to go by bike. Maybe I should have chosen to
go to the shop by my shiny car, my shiny helicopter, my elephant?".
P.Krumins
Nov 14 '05 #6
Charles Ulrich wrote:

Greetings,

I hope my greenness isn't showing too bad by asking this, but I ran across
this trivial program today that left me flabbergasted:

#define MESSAGE "This account is currently not available.\n"

int
main(int argc, char *argv[])
{
write(STDOUT_FI LENO, MESSAGE, sizeof(MESSAGE) );
_exit(1);
}

This is an excerpt from the newly-rewritten nologin(8) in FreeBSD. I am
not willing to accept that the person who committed this code is a fool,
thus I have to conclude that I just don't understand why exactly the
following isn't good enough for such a trivial program:

puts("This account is currently not available.");


Various people have speculated about the pros and
cons and possible motivations for this code, but no one
yet seems to have mentioned the more interesting aspect:
the code outputs one more character than it (probably)
intends.

If the trailing '\0' is actually required for some
peculiar reason, that's unusual enough that a comment
in the source should be mandatory. If (as seems more
likely) the trailing '\0' is a bug, the code stands as
an object lesson in why stupid optimizations are stupid.

--
Er*********@sun .com
Nov 14 '05 #7
Keith Thompson wrote:
Charles Ulrich <NO***@BLOODYse curenym.SPAMnet > writes:
I hope my greenness isn't showing too bad by asking this, but I
ran across this trivial program today that left me flabbergasted:

#define MESSAGE "This account is currently not available.\n"

int
main(int argc, char *argv[])
{
write(STDOUT_FI LENO, MESSAGE, sizeof(MESSAGE) );
_exit(1);
}

This is an excerpt from the newly-rewritten nologin(8) in FreeBSD.

[...]

Presumably the FreeBSD nologin program doesn't need to be portable
to anything other than FreeBSD. Given that constraint, I suppose
there's not much advantage in using the portable puts() rather than
the relatively non-portable write().

Having said that, it's not how I would have written it. puts() or
printf() would make for more legible code.


This may have to run in circumstances where the C initialization
cannot function, thus making stdout unavailable.

--
Chuck F (cb********@yah oo.com) (cb********@wor ldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net> USE worldnet address!
Nov 14 '05 #8
On Mon, 12 Jan 2004 23:09:24 +0000, Peteris Krumins wrote:
Finding an answer to such silly problem is the same as asking and trying
to find an answer to a problem like "I have to go to the shop which is
across a street, I chose to go by bike. Maybe I should have chosen to
go to the shop by my shiny car, my shiny helicopter, my elephant?".
P.Krumins


It's pretty easy to say that in retrospect, isn't it? But look at it from
my point of view. I'm just now emerging from being a complete novice in C
and I stumbled across some code that made little sense given its
elementary job. I am at too low a skill level to be deciding for myself
what constitutes a "silly problem" and what does not. _That's why I asked._

Thanks and gratitude to those who provided helpful input.

Charles Ulrich
Nov 14 '05 #9
On 12 Jan 2004 20:10:59 GMT, Alexander Bartolich
<al************ *****@gmx.at> wrote:
begin followup to Charles Ulrich:
int
main(int argc, char *argv[])
{
write(STDOUT_FI LENO, MESSAGE, sizeof(MESSAGE) );
_exit(1);
}


write(2) is a system call.
_exit(2) is a system call.
[...] I just don't understand why exactly the following isn't
good enough for such a trivial program:

puts("This account is currently not available.");


puts(3) is part of the C run time library.

By using nothing but system calls the total size of the resulting
binary can be minimized. See option -nostdlib of gcc.


Also, when the C standard library is shared, and its file is corrupt
or inaccessible, minimum programs can run.

- Sev

Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
55600
by: Pontus F | last post by:
Hi I am learning C++ and I'm still trying to get a grip of pointers and other C/C++ concepts. I would appreciate if somebody could explain what's wrong with this code: ---begin code block--- #include "stdio.h" #include "string.h" void printText(char c){
8
9859
by: Brandon McCombs | last post by:
This may be the wrong group but I didn't see anything for VC++ so I'm trying here. I have a C++ book by Deitel and Deitel that says I can use fstream File("data.dat", ios::in | ios::out | ios::binary) to declare a file object with read/write modes turned on for working with binary data. I've tried this and my file is not created. The only time it is created is when I specify ifstream or ofstream but not fstream. I've tried removing the...
7
6159
by: Yandos | last post by:
Hello all, I have maybe a trivial question, but I cannot think out what is wrong :( How do i detect EOF correctly when i read from stdin? Am I doing it wrong? <pipetest.c> #include <stdio.h> int main(void) { char ch;
121
10186
by: typingcat | last post by:
First of all, I'm an Asian and I need to input Japanese, Korean and so on. I've tried many PHP IDEs today, but almost non of them supported Unicode (UTF-8) file. I've found that the only Unicode support IDEs are DreamWeaver 8 and Zend PHP Studio. DreamWeaver provides full support for Unicode. However, DreamWeaver is a web editor rather than a PHP IDE. It only supports basic IntelliSense (or code completion) and doesn't have anything...
42
9902
by: Prashanth Badabagni | last post by:
Hi, Can any body tell me how to print "hello,world" with out using semicolon Thanks in advance .. Bye Prashanth Badabagni
6
3502
by: hpy_awad | last post by:
I am writing stings ((*cust).name),((*cust).address)to a file using fgets but rabish is being wrote to that file ? Look to my source please and help me finding the reason why this rabish is being written. /* Book name : File name : E:\programs\cpp\iti01\ch10\ex09_5p1.cpp Program discription: Adding name,Address to customer_record SETUP PROGRAM
1
4809
by: noleander | last post by:
Hi. I've got a C++ program written in Visual C++ 2003. The program is trivial, created with the Program-creation wizard: used the .NET "Form" template. The program has a trivial single-pane form GUI. I've got some stdout print statements in the code ... but I cannot find where in the world the output text is appearing. For printing I tried both: printf ("Hello world\n"); and Console::Write ("Hello World\n");
27
3243
by: lovecreatesbea... | last post by:
This code snippet is an exercise on allocating two dimension array dynamically. Though this one is trivial, is it a correct one? Furthermore, when I tried to make these changes to the original example: for (i = 0; i < ROW + 2; ++i){ /*line 14*/ strcpy(array, "C! C!"); /*line 15*/ Apparently, the modified code wrote to the memory unit outside the allocated array, but the program ran well and there was no Segmentation
23
3007
by: asit dhal | last post by:
hello friends, can anyone explain me how to use read() write() function in C. and also how to read a file from disk and show it on the monitor using onlu read(), write() function ??????
0
9685
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9536
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10468
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10245
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10021
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7559
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5458
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4131
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2933
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.